使用TaskManager爬取2万条代理IP实现自动投票功能
HtmlAgilityPack解析HTML,Quart.net。
阅读目录
- 代理IP介绍
- HtmlAgilityPack使用
- 代理IP爬虫实现
- 自动投票简单实现
- 总结
有了这么多在线的代理IP可以解决文章开头的问题4了,可是还有个问题这些数据都是网页上的,我在代码里面怎么使用呢?这就用到了HtmlAgilityPack工具包,看名称就能猜到是用来解析HTML的。
回到顶部HtmlAgilityPack是一个开源的解析HTML元素的类库,最大的特点是可以通过XPath来解析HMTL,如果您以前用C#操作过XML,那么使用起HtmlAgilityPack也会得心应手。解析简单的HTML
string HTML = @"回到顶部IpProxyGet.cs源码可到文章末尾自行下载。简单解析测试 "; 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();
1 cn
////// 获取总页数 /// /// 总页数 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.rarTaskManagerSVN地址:http://code.taobao.org/svn/TaskManagerPub/Branch 使用svn checkout指令进行下载。
GitHub地址:https://github.com/CrazyJson/TaskManager
体验工具下载地址:TaskManager 解压后文件执行合并SQL,修改Config.xml数据库连接,使用WSWinForm进行安装。
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。
因为,我的写作热情也离不开您的肯定支持。
感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是焰尾迭 。