话说某天心血来潮想到一个问题,朋友圈里面经常有人发投票链接,让帮忙给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

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[].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
{
var request = (HttpWebRequest)WebRequest.Create(Url);
          request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
WebProxy myProxy = new WebProxy("192.168.15.11", 8015);
//建议连接(代理需要身份认证,才需要用户名密码)
myProxy.Credentials = new NetworkCredential("admin", "123456");
//设置请求使用代理信息
request.Proxy = myProxy;
// Get the response instance.
System.Net.WebResponse wResp = request.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 > )
{
int page;
if (int.TryParse(res[res.Count - ].InnerText, out page))
{
return page;
}
}
return ;
}

解析每一页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 > )
{
LogHelper.WriteLog(string.Format("当前页码{0},请求地址{1},共{2}条数据", i, url, trs.Count));
for (int j = ; j < trs.Count; j++)
{
nodes = trs[j].SelectNodes("td");
if (nodes != null && nodes.Count > )
{
ip = nodes[].InnerText.Trim();
if (Param.IsPingIp && !Ping(ip))
{
continue;
}
//有效的IP才添加
item = new IPProxy(); node = nodes[].FirstChild;
if (node != null)
{
atr = node.Attributes["alt"];
if (atr != null)
{
item.Country = atr.Value.Trim();
}
} item.IP = ip;
item.Port = nodes[].InnerText.Trim();
item.ProxyIp = GetIP(item.IP, item.Port);
item.Position = nodes[].InnerText.Trim();
item.Anonymity = nodes[].InnerText.Trim();
item.Type = nodes[].InnerText.Trim(); node = nodes[].SelectSingleNode("div[@class='bar']");
if (node != null)
{
atr = node.Attributes["title"];
if (atr != null)
{
item.Speed = atr.Value.Trim();
}
} node = nodes[].SelectSingleNode("div[@class='bar']");
if (node != null)
{
atr = node.Attributes["title"];
if (atr != null)
{
item.ConnectTime = atr.Value.Trim();
}
}
item.VerifyTime = nodes[].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进行安装。

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

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

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

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

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

  1. 这届网友实在是太有才了!用python爬取15万条《我是余欢水》弹幕

    年初时我们用数据解读了几部热度高,但评分差强人意的国产剧,而最近正午阳光带着两部新剧来了,<我是余欢水>和<清平乐>,截止到目前为止,这两部剧在豆瓣分别为7.5分和7.9分,算 ...

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

    需求: 获取西刺网代理ip信息,包括ip地址.端口号.ip类型 西刺网:http://www.xicidaili.com/nn/ 那,如何解决这个问题? 分析页面结构和url设计得知: 数据都在本页面 ...

  3. 爬取软考试题系列之ip自动代理

    马上5月份有个软件专业等级考试,以下简称软考,为了更好的复习备考,我打算抓取www.rkpass.com网上的软考试题. 以上为背景. 很久没有更新博客园的博客了,所以之前的代码没有及时的贴出来,咱们 ...

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

    1.POI爬取方法说明 1.1AK申请 登录百度账号,在百度地图开发者平台的API控制台申请一个服务端的ak,主要用到的是Place API.检校方式可设置成IP白名单,IP直接设置成了0.0.0.0 ...

  5. 【Python3爬虫】我爬取了七万条弹幕,看看RNG和SKT打得怎么样

    一.写在前面 直播行业已经火热几年了,几个大平台也有了各自独特的“弹幕文化”,不过现在很多平台直播比赛时的弹幕都基本没法看的,主要是因为网络上的喷子还是挺多的,尤其是在观看比赛的时候,很多弹幕不是喷选 ...

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

    一提到程序猿,我们的脑子里就会出现这样的画面: 或者这样的画面: 心头萦绕的字眼是:秃头.猝死.眼镜.黑白 T 恤.钢铁直男-- 而真实的程序猿们,是每天要和无数数据,以及数十种编程语言打交道.上能手 ...

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

    ip地址查询的全代码: 智力使用ip183网站进行ip地址归属地的查询,我们在查询的过程是通过构造url进行查询的,将要查询的ip地址以参数的形式添加在ip183url后面即可. #ip地址查询的全代 ...

  8. [转] 分组排序取前N条记录以及生成自动数字序列,类似group by后 limit

    前言:        同事的业务场景是,按照cid.author分组,再按照id倒叙,取出前2条记录出来.        oracle里面可以通过row_number() OVER (PARTITIO ...

  9. HtmlUnit爬取Ajax动态生成的网页以及自动调用页面javascript函数

    HtmlUnit官网的介绍: HtmlUnit是一款基于Java的没有图形界面的浏览器程序.它模仿HTML document并且提供API让开发人员像是在一个正常的浏览器上操作一样,获取网页内容,填充 ...

随机推荐

  1. Elasticsearch配置详解、文档元数据

    目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 1.Elasticsearch配置文件详解 a. 在上面博客中,我们已经安装并且成功 ...

  2. jQuery演示8种不同的图片遮罩层动画效果

    效果预览 下载地址 jQuery插件大全 实例代码 <div class="container"> <h1>jQuery图标和文章动画效果</h1&g ...

  3. 在其他系统Iframe中显示SharePoint 页面

    前段时间在做一个项目,要求将SharePoint 的 OWA(Office Web Apps)中的文档显示页面嵌入到另外一个OA系统中,提供给用户可以通过浏览器查看SharePoint文档的能力. 嵌 ...

  4. Android开发过程遇到的问题小计

    1.在真机上正常运行,而模拟器会报出一些so文件找不到 unexpected e_machine: 40. 解决方法:采用x86的NDK进行编译,问题解决.

  5. iOS 9.3真机适配-Could not find Developer Disk Image问题

    Could not find Developer Disk Image 这是由于真机系统过高或者过低,Xcode中没有匹配的配置包文件,我们可以通过这个路径进入配置包的存放目录: /Applicati ...

  6. Mindjet MindManager思维导图工具的使用 - 项目管理系列文章

    在项目管理过程中,不可避免的要使用到各种各样的项目管理工具.本文就对我自己使用的Mindjet Manager进行一下介绍,推荐给大家使用. 1.  打开软件 这里使用了2012版 2.  软件的界面 ...

  7. Tomcat:利用Apache配置反向代理、负载均衡

    本篇主要介绍apache配置反向代理,介绍了两种情况:第一种是,只使用apache配置反向代理:第二种是,apache与应用服务器(tomcat)结合,配置反向代理,同时了配置了负载均衡. 准备工作 ...

  8. MongoDB学习笔记~Update方法更新集合属性后的怪问题

    回到目录 在对MongoDB进行封装后,对于Update更新对象里的集合属性时出现了一个现象,让人感到很恶心,人家更新前是个美丽的Array,但是更新之后集合对象变成了键值对,键是集合的类型名称,值是 ...

  9. shell中各种括号的作用()、(())、[]、[[]]、{}

    一.小括号,圆括号() 1.单小括号 ()    ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有 ...

  10. ubuntu与centos安装软件的不同点总结

    ubuntu与redhat系列的linux操作系统安装软件区别是很大的.下表列出了两者之间的对比.