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

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

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(完全开源的),使之成为一款能够提高生活便捷 性的工具,添加很多新任务。比如:第二天要下雨或者下雪,发个邮件提醒,带上雨伞…。好了到了放出源代码的时间了。敬请期待下一篇!

(0)

相关推荐

  • Python实现检测代理IP是否可以翻墙

    那堵墙着实可恨!身处IT这个圈子,经常需要用gg查资料(你也可以用来访问1024,^_^...).当然,你也可以用百度.其实也不是我不爱用百度,是有缘由的,且听我细细道来.有一次闲得蛋疼,想看看会不会有人抄袭我的博客(尽管博客学得不咋地),于是百度了一下,结果是惊人的.我发现我自己写的博客,即使是拿整个标题去搜索,往往搜不到,搜到的是一堆爬虫爬去的结果.具体是哪些,这里就不说了,各自可以拿自己的博客试一下.以前总是手工收集几个IP用一段时间,失效了以后再重新收集几个,如此反复,烦!于是,想着写个

  • php代码检查代理ip的有效性

    本文实例为大家分享了检查代理ip有效性php代码,稳定性,如错误率和查询用时 /** +----------------------------------------------------------------------------- * 检查代理ip信息有效性 +----------------------------------------------------------------------------- * @param string $proxy_ip [117.95.1

  • 30个php操作redis常用方法代码例子

    redis的操作很多的,以前看到一个比较全的博客,但是现在找不到了.查个东西搜半天,下面整理一下php处理redis的例子,个人觉得常用一些例子.下面的例子都是基于php-redis这个扩展的. 1,connect 描述:实例连接到一个Redis. 参数:host: string,port: int 返回值:BOOL 成功返回:TRUE;失败返回:FALSE 示例: 复制代码 代码如下: <?php  $redis = new redis();  $result = $redis->conne

  • 通过Python爬虫代理IP快速增加博客阅读量

    写在前面 题目所说的并不是目的,主要是为了更详细的了解网站的反爬机制,如果真的想要提高博客的阅读量,优质的内容必不可少. 了解网站的反爬机制 一般网站从以下几个方面反爬虫: 1. 通过Headers反爬虫 从用户请求的Headers反爬虫是最常见的反爬虫策略.很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer). 如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agen

  • 64位Windows下安装Redis教程

    Redis对于Linux是官方支持的,安装和使用没有什么好说的,普通使用按照官方指导,5分钟以内就能搞定.详情请参考:http://redis.io/download 但有时候又想在windows下折腾下Redis,可以从redis下载页面看到如下提示: 复制代码 代码如下: Win64 Unofficial The Redis project does not directly support Windows,  however the Microsoft Open Tech group de

  • 利用Python爬取可用的代理IP

    前言 就以最近发现的一个免费代理IP网站为例:http://www.xicidaili.com/nn/.在使用的时候发现很多IP都用不了. 所以用Python写了个脚本,该脚本可以把能用的代理IP检测出来. 脚本如下: #encoding=utf8 import urllib2 from bs4 import BeautifulSoup import urllib import socket User_Agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv

  • Redis教程之代理ip池设计方法详解

    前言 众所周知代理 ip 因为配置简单而且廉价,经常用来作为反反爬虫的手段,但是稳定性一直是其诟病.筛选出优质的代理 ip 并不简单,即使付费购买的代理 ip 源,卖家也不敢保证 100% 可用:另外代理 ip 的生命周期也无法预知,可能上一秒能用,下一秒就扑街了.基于这些原因,会给使用代理 ip 的爬虫程序带来很多不稳定的因素.要排除代理 ip 的影响,通常的做法是建一个代理 ip 池,每次请求前来池子取一个 ip,用完之后归还,保证池子里的 ip 都是可用的.本文接下来就探讨一下,如何使用

  • 超强、超详细Redis数据库入门教程

    [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用redis 4.学会安装redis 5.学会启动redis 6.使用redis客户端 7.redis数据结构 – 简介 8.redis数据结构 – strings 9.redis数据结构 – lists 10.redis数据结构 – 集合 11.redis数据结构 – 有序集合 12.redis数据结构 – 哈希 13.聊聊redis持久化 – 两种方式 14.聊聊redis持久化 – RDB 15.聊聊redis持

  • redis 队列操作的例子(php)

    入队操作 复制代码 代码如下: <?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); while(True){ try{ $value = 'value_'.date('Y-m-d H:i:s'); $redis->LPUSH('key1',$value); sleep(rand()%3); echo $value."\n"; }catch(Exception $e){ echo $e->g

  • redis常用命令、常见错误、配置技巧等分享

    1. redis查看当前所有的key 复制代码 代码如下: KEYS * 2. 查看当前redis的配置信息 复制代码 代码如下: CONFIG GET * 3. MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis

随机推荐