使用TaskManager爬取2万条代理IP实现自动投票功能

  话说某天心血来潮想到一个问题,朋友圈里面经常有人发投票链接,让帮忙给XX投票,以前呢会很自觉打开链接帮忙投一票。可是这种事做多了就会考虑能不能使用工具来进行投票呢,身为一名程序猿决定研究解决这个问题。于是有了以下思考

  1.是否能一个人投多票,如果不行又是什么限制了一人投多票?

  答:投票网站限制了一个IP或者一个用户只能投一票,防止恶意刷票行为

  2.如果是一个IP一票那是否代表着多个IP就能投多票了呢?

  答:答案是肯定的

  3.用什么方法能够在代码里面改变自己请求的IP?

  答:HTTP请求的时候设置代理IP

  4.多个代理IP从哪里获取,获取到之后我又该如何使用代码自动化投票?

  答:请看文章后面内容

  本篇将介绍TaskManager内置任务-代理IP爬虫实现细节,你需要准备的知识:HtmlAgilityPack解析HTML,Quart.net

阅读目录

  • 代理IP介绍
  • HtmlAgilityPack使用
  • 代理IP爬虫实现
  • 自动投票简单实现
  • 总结

回到顶部

代理IP介绍

  百度百科介绍:代理(英语:Proxy),也称网络代理,是一种特殊的网络服务,允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。一些网关、路由器等网络设备具备网络代理功能。一般认为代理服务有利于保障网络终端的隐私或安全,防止攻击。

  目前有很多厂商提供代理IP在线获取,但是很多都是提供几十个试用的,如果想使用更多的代理IP,则需付费购买。这里我找到了一个提供很多代理IP的网站,可以自行百度“代理ip”(以免认为我打广告),或者参考开源TaskManager介绍这篇文章。

  有了这么多在线的代理IP可以解决文章开头的问题4了,可是还有个问题这些数据都是网页上的,我在代码里面怎么使用呢?这就用到了HtmlAgilityPack工具包,看名称就能猜到是用来解析HTML的。

回到顶部

HtmlAgilityPack使用

  HtmlAgilityPack是一个开源的解析HTML元素的类库,最大的特点是可以通过XPath来解析HMTL,如果您以前用C#操作过XML,那么使用起HtmlAgilityPack也会得心应手。

  解析简单的HTML

string HTML = @"<html><head><title>简单解析测试</title></head><body>
                    <div id=‘div1‘ title=‘div1‘>
                        <table>
                             <tr>
                                <td>1</td>
                                <td title=‘cn‘>cn</td>
                            </tr>
                        </table>
                    </div>
                </body></html>";
            var doc = new HtmlDocument();
            doc.LoadHtml(HTML);
            //输出页面标题
            Console.WriteLine("页面title:"+doc.DocumentNode.SelectSingleNode("/html/head/title").InnerText);
            //获取div1节点  方式1
            HtmlNode divNode1 = doc.GetElementbyId("div1");
            //获取div1节点  方式2
            HtmlNode divNode2 = doc.DocumentNode.SelectSingleNode("//div[@id=‘div1‘]");
            //判断节点1和节点2是否相同
            Console.WriteLine("断节点1和节点2是否相同:" + (divNode1 == divNode2));
            //获取页面所有table
            HtmlNodeCollection tableCollection = doc.DocumentNode.SelectNodes("//table");
            Console.WriteLine("页面table数量:"+tableCollection.Count);
            //获取table下所有td并输出信息
            HtmlNodeCollection tdCollection = tableCollection[0].SelectNodes("tr/td");
            foreach (var td in tdCollection)
            {
                HtmlAttribute atr = td.Attributes["title"];
                Console.WriteLine("td InnerText:" + td.InnerText + " | td title属性值:" + (atr == null ? "" : atr.Value));
            }
            Console.Read();

回到顶部

代理IP爬虫实现

  会了HtmlAgilityPack的一些简单操作之后进入正式爬取过程,由于需要爬取的网页带IP封锁功能(一段时间请求频率过高封锁当前IP),在设计过程中我采用了爬取五次自动换代理IP突破网站限制(感觉自己坏坏的)。

              整体实现逻辑

在.net里面使用WebRequest可以模拟HTTP的get Post请求,最终要的一点能设置请求时使用的代理IP,重点关注我标红的代码

/// <summary>
        /// 代理使用示例
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetUrltoHtml(string Url, string type)
        {
            try
            {
                System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);

                WebProxy myProxy = new WebProxy("192.168.15.11", 8015);
                //建议连接(代理需要身份认证,才需要用户名密码)
                myProxy.Credentials = new NetworkCredential("admin", "123456");
                //设置请求使用代理信息
                wReq.Proxy = myProxy;
                // Get the response instance.
                System.Net.WebResponse wResp = wReq.GetResponse();
                System.IO.Stream respStream = wResp.GetResponseStream();
                // Dim reader As StreamReader = New StreamReader(respStream)
                using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream, Encoding.GetEncoding(type)))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (System.Exception ex)
            {
                //errorMsg = ex.Message;
            }
            return "";
        }

了解如何使用代理IP,离我们的目标又近了一步,下面就是代理IP获取的实现了,由于代码有点多,我这里只贴出重要部分,IpProxyGet.cs源码可到文章末尾自行下载。

        /// <summary>
        /// 获取总页数
        /// </summary>
        /// <returns>总页数</returns>
        private static int GetTotalPage(string IPURL, string ProxyIp)
        {
            var doc = new HtmlDocument();
            doc.LoadHtml(GetHTML(IPURL, ProxyIp));
            var res = doc.DocumentNode.SelectNodes(@"//div[@class=‘pagination‘]/a");
            if (res != null && res.Count > 2)
            {
                int page;
                if (int.TryParse(res[res.Count - 2].InnerText, out page))
                {
                    return page;
                }
            }
            return 1;
        }

解析每一页HTML数据

 /// <summary>
        /// 解析每一页数据
        /// </summary>
        /// <param name="param"></param>
        private static void DoWork(object param)
        {
            //参数还原
            Hashtable table = param as Hashtable;
            int start = Convert.ToInt32(table["start"]);
            int end = Convert.ToInt32(table["end"]);
            List<IPProxy> list = table["list"] as List<IPProxy>;
            ProxyParam Param = table["param"] as ProxyParam;

            //页面地址
            string url = string.Empty;
            string ip = string.Empty;
            IPProxy item = null;
            HtmlNodeCollection nodes = null;
            HtmlNode node = null;
            HtmlAttribute atr = null;
            for (int i = start; i <= end; i++)
            {
                LogHelper.WriteLog(string.Format("开始解析,页码{0}~{1},当前页码{2}", start, end, i));
                url = string.Format("{0}/{1}", Param.IPUrl, i);
                var doc = new HtmlDocument();
                doc.LoadHtml(GetHTML(url, Param.ProxyIp));
                //获取所有数据节点tr
                var trs = doc.DocumentNode.SelectNodes(@"//table[@id=‘ip_list‘]/tr");
                if (trs != null && trs.Count > 1)
                {
                    LogHelper.WriteLog(string.Format("当前页码{0},请求地址{1},共{2}条数据", i, url, trs.Count));
                    for (int j = 1; j < trs.Count; j++)
                    {
                        nodes = trs[j].SelectNodes("td");
                        if (nodes != null && nodes.Count > 9)
                        {
                            ip = nodes[2].InnerText.Trim();
                            if (Param.IsPingIp && !Ping(ip))
                            {
                                continue;
                            }
                            //有效的IP才添加
                            item = new IPProxy();

                            node = nodes[1].FirstChild;
                            if (node != null)
                            {
                                atr = node.Attributes["alt"];
                                if (atr != null)
                                {
                                    item.Country = atr.Value.Trim();
                                }
                            }

                            item.IP = ip;
                            item.Port = nodes[3].InnerText.Trim();
                            item.ProxyIp = GetIP(item.IP, item.Port);
                            item.Position = nodes[4].InnerText.Trim();
                            item.Anonymity = nodes[5].InnerText.Trim();
                            item.Type = nodes[6].InnerText.Trim();

                            node = nodes[7].SelectSingleNode("div[@class=‘bar‘]");
                            if (node != null)
                            {
                                atr = node.Attributes["title"];
                                if (atr != null)
                                {
                                    item.Speed = atr.Value.Trim();
                                }
                            }

                            node = nodes[8].SelectSingleNode("div[@class=‘bar‘]");
                            if (node != null)
                            {
                                atr = node.Attributes["title"];
                                if (atr != null)
                                {
                                    item.ConnectTime = atr.Value.Trim();
                                }
                            }
                            item.VerifyTime = nodes[9].InnerText.Trim();
                            list.Add(item);
                        }
                    }
                    LogHelper.WriteLog(string.Format("当前页码{0},共{1}条数据", i, trs.Count));
                }
                LogHelper.WriteLog(string.Format("结束解析,页码{0}~{1},当前页码{2}", start, end, i));
            }
        }

最终会获取2万多条数据

回到顶部

自动投票简单实现

  这里使用.net的WebBrowser控件来加载页面,最终效果如下

 #region 设置代理IP
        private void button2_Click(object sender, EventArgs e)
        {
            string proxy = this.textBox1.Text;
            RefreshIESettings(proxy);
            IEProxy ie = new IEProxy(proxy);
            ie.RefreshIESettings();
            //MessageBox.Show(ie.RefreshIESettings().ToString());
        }
        #endregion
        #region 取消代理IP
        private void button3_Click(object sender, EventArgs e)
        {
            IEProxy ie = new IEProxy(null);
            ie.DisableIEProxy();
        }
        #endregion
        #region 打开网页
        private void button1_Click(object sender, EventArgs e)
        {
            string url = txt_url.Text.Trim();
            if (string.IsNullOrEmpty(url))
            {
                MessageBox.Show("请输入要打开的网址");
                return;
            }
            this.webBrowser1.Navigate(url, null, null, null);
        }
        #endregion

回到顶部

总结

本篇要介绍的内容到此结束了,下面写点我的期待!希望有喜欢的朋友一起来完善TaskManager(完全开源的),使之成为一款能够提高生活便捷性的工具,添加很多新任务。比如:第二天要下雨或者下雪,发个邮件提醒,带上雨伞...。好了到了放出源代码的时间了。敬请期待下一篇!

  简单投票源代码:http://files.cnblogs.com/files/yanweidie/SimpleIP.rar

TaskManagerSVN地址:http://code.taobao.org/svn/TaskManagerPub/Branch   使用svn checkout指令进行下载。

  GitHub地址:https://github.com/CrazyJson/TaskManager

体验工具下载地址:TaskManager  解压后文件执行合并SQL,修改Config.xml数据库连接,使用WSWinForm进行安装。

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。
因为,我的写作热情也离不开您的肯定支持。

感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是焰尾迭 。

时间: 2024-11-12 10:30:20

使用TaskManager爬取2万条代理IP实现自动投票功能的相关文章

爬取西刺网代理ip,并把其存放mysql数据库

需求: 获取西刺网代理ip信息,包括ip地址.端口号.ip类型 那,如何解决这个问题? 分析页面结构和url设计得知: 数据都在本页面可以全部获取,没有单独的详情页面 下一页通过更改当前页面最后url后缀进行跳转页面,那我实现URL的拼接不就解决这个问题了 那,软件的运行环境? python3.5 scrapy twisted request pymysql 以上是第三方包,通过pip安装 MySQL服务 其中db,user,password的值根据实际情况而定 #!/usr/bin/pytho

网络爬虫+HtmlAgilityPack+windows服务从博客园爬取20万博文

网络爬虫+HtmlAgilityPack+windows服务从博客园爬取20万博文 1.前言 最新在公司做一个项目,需要一些文章类的数据,当时就想到了用网络爬虫去一些技术性的网站爬一些,当然我经常去的就是博客园,于是就有下面的这篇文章. 2.准备工作 我需要把我从博客园爬取的数据,保存起来,最好的方式当然是保存到数据库中去了,好了我们先建一个数据库,在来一张表,保存我们的数据,其实都很简单的了啊,如下图所示 BlogArticleId博文自增ID,BlogTitle博文标题,BlogUrl博文地

项目实战!爬取5万篇好奇心日报文章,适合小白练手的实战案例!

Python的知识很多,基本的入门就有很多东西要学,还有各种合样的库要学习.很多同学学了一段时间,进展很慢,学了前面忘了后面!要么就是揠苗助长找一些特别难的例子,结果太难了,失去信心,完全没有成就感! 个人建议是学Python应该趣味性结合,如果跟自己平时的工作相关的应用更好,如果没有,找到合适的例子,通俗有趣的例子非常重要.今天我就给大家介绍一个非常简单的爬虫小例子,来综合练习,非常不错! 要点: 练习基本的入门知识 练习Python类的使用 练习爬虫的最简单使用 练习最简单的数据库的使用 0

百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制11。

1.POI爬取方法说明 1.1AK申请 登录百度账号,在百度地图开发者平台的API控制台申请一个服务端的ak,主要用到的是Place API.检校方式可设置成IP白名单,IP直接设置成了0.0.0.0/0比较方便. Place API 提供的接口用于返回查询某个区域的某类POI数据,且提供单个POI的详情查询服务,用户可以使用C#.C++.Java,Python等开发语言发送请求,接收json.xml的数据.关于Place API的具体使用可以参考:Place API Web服务API 1.2爬

表哥用Python爬取数千条淘宝商品数据后,发现淘宝这些潜规则!

本文记录了笔者用 Python 爬取淘宝某商品的全过程,并对商品数据进行了挖掘与分析,最终得出结论. 项目内容 本案例选择商品类目:沙发. 数量:共 100 页 4400 个商品. 筛选条件:天猫.销量从高到低.价格 500 元以上. 项目目的 对商品标题进行文本分析,词云可视化 不同关键词 word 对应的 sales 的统计分析 商品的价格分布情况分析 商品的销量分布情况分析 不同价格区间的商品的平均销量分布 商品价格对销量的影响分析 商品价格对销售额的影响分析 不同省份或城市的商品数量分布

Python 爬取 11 万 Java 程序员信息竟有这些重大发现!

一提到程序猿,我们的脑子里就会出现这样的画面: 或者这样的画面: 心头萦绕的字眼是:秃头.猝死.眼镜.黑白 T 恤.钢铁直男-- 而真实的程序猿们,是每天要和无数数据,以及数十种编程语言打交道.上能手握亿万数据面不改色,下能修改 Bug 奋战两昼夜.他们热爱生活,讨厌 Bug-- 时代在进步,今天的程序猿,你真的了解么? 程序猿的生活,永远和编程语言有关.目前市面上主流的编程语言有 JavaScript.Python.Ruby.PHP.C++.C#. Go.C 和 TypeScript. 时间有

练习-爬取某图片及查询IP地址

爬取某图片的程序: #图片爬取全代码 import requests import os url='http://img0.dili360.com/rw9/ga/M01/4A/3D/wKgBy1p6qJ6ALyaOADWDaIwa9uw587.tub.jpg' root='D:/北理工爬虫课程/' path=root+url.split('/')[-1]#被加数表示的是图片路径中图片的名字加后缀 try: if not os.path.exists(root): os.mkdir(root)#如

python requests库爬取网页小实例:ip地址查询

ip地址查询的全代码: 智力使用ip183网站进行ip地址归属地的查询,我们在查询的过程是通过构造url进行查询的,将要查询的ip地址以参数的形式添加在ip183url后面即可. #ip地址查询的全代码 import requests url="http://m.ip138.com/ip.asp?ip=" try: r=requests.get(url+'202.204.80.112') r.raise_for_status() r.encoding=r.apparent_encodi

python日常—爬取豆瓣250条电影记录

# 感兴趣的同仁可以相互交流哦 import requests import lxml.html,csv doubanUrl = 'https://movie.douban.com/top250?start={}&filter=' def getSource(doubanUrl): response = requests.get(doubanUrl) # 获取网页 response.encoding = 'utf-8' # 修改编码 return response.content #获取源码 d