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


HtmlAgilityPack解析HTML,Quart.net。

阅读目录

  • 代理IP介绍
  • HtmlAgilityPack使用
  • 代理IP爬虫实现
  • 自动投票简单实现
  • 总结
回到顶部开源TaskManager介绍这篇文章。

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

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

  解析简单的HTML

string HTML = @"简单解析测试
                    
1 cn
"; 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();
回到顶部IpProxyGet.cs源码可到文章末尾自行下载。

        /// 
        /// 获取总页数
        /// 
        /// 总页数
        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数据

 /// 
        /// 解析每一页数据
        /// 
        /// 
        private static void DoWork(object param)
        {
            //参数还原
            Hashtable table = param as Hashtable;
            int start = Convert.ToInt32(table["start"]);
            int end = Convert.ToInt32(table["end"]);
            List list = table["list"] as List;
            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万多条数据

回到顶部回到顶部https://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进行安装。

      

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

如果,想给予我更多的鼓励,求打

因为,我的写作热情也离不开您的肯定支持。

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