首页 > 编程 > C# > 正文

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

2019-10-29 21:38:32
字体:
来源:转载
供稿:网友

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

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

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

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

答:答案是肯定的

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

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

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

答:请看文章后面内容

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

代理IP介绍

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

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

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

HtmlAgilityPack使用

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

解析简单的HTML

 

 
  1. string HTML = @"<html><head><title>简单解析测试</title></head><body>  
  2. <div id='div1' title='div1'>  
  3. <table>  
  4. <tr>  
  5. <td>1</td>  
  6. <td title='cn'>cn</td>  
  7. </tr>  
  8. </table>  
  9. </div>  
  10. </body></html>";  
  11. var doc = new HtmlDocument();  
  12. doc.LoadHtml(HTML);  
  13. //输出页面标题  
  14. Console.WriteLine("页面title:"+doc.DocumentNode.SelectSingleNode("/html/head/title").InnerText);  
  15. //获取div1节点 方式1  
  16. HtmlNode divNode1 = doc.GetElementbyId("div1");  
  17. //获取div1节点 方式2  
  18. HtmlNode divNode2 = doc.DocumentNode.SelectSingleNode("//div[@id='div1']");  
  19. //判断节点1和节点2是否相同  
  20. Console.WriteLine("断节点1和节点2是否相同:" + (divNode1 == divNode2));  
  21. //获取页面所有table  
  22. HtmlNodeCollection tableCollection = doc.DocumentNode.SelectNodes("//table");  
  23. Console.WriteLine("页面table数量:"+tableCollection.Count);  
  24. //获取table下所有td并输出信息  
  25. HtmlNodeCollection tdCollection = tableCollection[0].SelectNodes("tr/td");  
  26. foreach (var td in tdCollection)  
  27. {  
  28. HtmlAttribute atr = td.Attributes["title"];  
  29. Console.WriteLine("td InnerText:" + td.InnerText + " | td title属性值:" + (atr == null ? "" : atr.Value));  
  30. }  
  31. Console.Read(); 

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

代理IP爬虫实现

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

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

整体实现逻辑

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

 

 
  1. /// <summary>  
  2. /// 代理使用示例  
  3. /// </summary>  
  4. /// <param name="Url"></param>  
  5. /// <param name="type"></param>  
  6. /// <returns></returns>  
  7. public static string GetUrltoHtml(string Url, string type)  
  8. {  
  9. try 
  10. {  
  11. System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);  
  12.  
  13. WebProxy myProxy = new WebProxy("192.168.15.11", 8015);  
  14. //建议连接(代理需要身份认证,才需要用户名密码)  
  15. myProxy.Credentials = new NetworkCredential("admin""123456");  
  16. //设置请求使用代理信息  
  17. wReq.Proxy = myProxy;  
  18. // Get the response instance.  
  19. System.Net.WebResponse wResp = wReq.GetResponse();  
  20. System.IO.Stream respStream = wResp.GetResponseStream();  
  21. // Dim reader As StreamReader = New StreamReader(respStream)  
  22. using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream, Encoding.GetEncoding(type)))  
  23. {  
  24. return reader.ReadToEnd();  
  25. }  
  26. }  
  27. catch (System.Exception ex)  
  28. {  
  29. //errorMsg = ex.Message;  
  30. }  
  31. return "";  

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

 

 
  1. /// <summary>  
  2. /// 获取总页数  
  3. /// </summary>  
  4. /// <returns>总页数</returns>  
  5. private static int GetTotalPage(string IPURL, string ProxyIp)  
  6. {  
  7. var doc = new HtmlDocument();  
  8. doc.LoadHtml(GetHTML(IPURL, ProxyIp));  
  9. var res = doc.DocumentNode.SelectNodes(@"//div[@class='pagination']/a");  
  10. if (res != null && res.Count > 2)  
  11. {  
  12. int page;  
  13. if (int.TryParse(res[res.Count - 2].InnerText, out page))  
  14. {  
  15. return page;  
  16. }  
  17. }  
  18. return 1;  

解析每一页HTML数据

 

 
  1. /// <summary>  
  2. /// 解析每一页数据  
  3. /// </summary>  
  4. /// <param name="param"></param>  
  5. private static void DoWork(object param)  
  6. {  
  7. //参数还原  
  8. Hashtable table = param as Hashtable;  
  9. int start = Convert.ToInt32(table["start"]);  
  10. int end = Convert.ToInt32(table["end"]);  
  11. List<IPProxy> list = table["list"] as List<IPProxy>;  
  12. ProxyParam Param = table["param"] as ProxyParam;  
  13. //页面地址  
  14. string url = string.Empty;  
  15. string ip = string.Empty;  
  16. IPProxy item = null;  
  17. HtmlNodeCollection nodes = null;  
  18. HtmlNode node = null;  
  19. HtmlAttribute atr = null;  
  20. for (int i = start; i <= end; i++)  
  21. {  
  22. LogHelper.WriteLog(string.Format("开始解析,页码{0}~{1},当前页码{2}", start, end, i));  
  23. url = string.Format("{0}/{1}", Param.IPUrl, i);  
  24. var doc = new HtmlDocument();  
  25. doc.LoadHtml(GetHTML(url, Param.ProxyIp));  
  26. //获取所有数据节点tr  
  27. var trs = doc.DocumentNode.SelectNodes(@"//table[@id='ip_list']/tr");  
  28. if (trs != null && trs.Count > 1)  
  29. {  
  30. LogHelper.WriteLog(string.Format("当前页码{0},请求地址{1},共{2}条数据", i, url, trs.Count));  
  31. for (int j = 1; j < trs.Count; j++)  
  32. {  
  33. nodes = trs[j].SelectNodes("td");  
  34. if (nodes != null && nodes.Count > 9)  
  35. {  
  36. ip = nodes[2].InnerText.Trim();  
  37. if (Param.IsPingIp && !Ping(ip))  
  38. {  
  39. continue;  
  40. }  
  41. //有效的IP才添加  
  42. item = new IPProxy();  
  43. node = nodes[1].FirstChild;  
  44. if (node != null)  
  45. {  
  46. atr = node.Attributes["alt"];  
  47. if (atr != null)  
  48. {  
  49. item.Country = atr.Value.Trim();  
  50. }  
  51. }  
  52. item.IP = ip;  
  53. item.Port = nodes[3].InnerText.Trim();  
  54. item.ProxyIp = GetIP(item.IP, item.Port);  
  55. item.Position = nodes[4].InnerText.Trim();  
  56. item.Anonymity = nodes[5].InnerText.Trim();  
  57. item.Type = nodes[6].InnerText.Trim();  
  58. node = nodes[7].SelectSingleNode("div[@class='bar']");  
  59. if (node != null)  
  60. {  
  61. atr = node.Attributes["title"];  
  62. if (atr != null)  
  63. {  
  64. item.Speed = atr.Value.Trim();  
  65. }  
  66. }  
  67. node = nodes[8].SelectSingleNode("div[@class='bar']");  
  68. if (node != null)  
  69. {  
  70. atr = node.Attributes["title"];  
  71. if (atr != null)  
  72. {  
  73. item.ConnectTime = atr.Value.Trim();  
  74. }  
  75. }  
  76. item.VerifyTime = nodes[9].InnerText.Trim();  
  77. list.Add(item);  
  78. }  
  79. }  
  80. LogHelper.WriteLog(string.Format("当前页码{0},共{1}条数据", i, trs.Count));  
  81. }  
  82. LogHelper.WriteLog(string.Format("结束解析,页码{0}~{1},当前页码{2}", start, end, i));  
  83. }  

最终会获取2万多条数据

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

自动投票简单实现

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

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

#region 设置代理IP

 

 
  1. private void button2_Click(object sender, EventArgs e)  
  2. {  
  3. string proxy = this.textBox1.Text;  
  4. RefreshIESettings(proxy);  
  5. IEProxy ie = new IEProxy(proxy);  
  6. ie.RefreshIESettings();  
  7. //MessageBox.Show(ie.RefreshIESettings().ToString());  
  8. }  
  9. #endregion  
  10. #region 取消代理IP  
  11. private void button3_Click(object sender, EventArgs e)  
  12. {  
  13. IEProxy ie = new IEProxy(null);  
  14. ie.DisableIEProxy();  
  15. }  
  16. #endregion  
  17. #region 打开网页  
  18. private void button1_Click(object sender, EventArgs e)  
  19. {  
  20. string url = txt_url.Text.Trim();  
  21. if (string.IsNullOrEmpty(url))  
  22. {  
  23. MessageBox.Show("请输入要打开的网址");  
  24. return;  
  25. }  
  26. this.webBrowser1.Navigate(url, nullnullnull);  
  27. }  
  28. #endregion 

总结

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表