使用TaskManager爬取2万条代理IP实现自动投票功能
话说某天心血来潮想到一个问题,朋友圈里面经常有人发投票链接,让帮忙给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实现自动投票功能的更多相关文章
- 这届网友实在是太有才了!用python爬取15万条《我是余欢水》弹幕
年初时我们用数据解读了几部热度高,但评分差强人意的国产剧,而最近正午阳光带着两部新剧来了,<我是余欢水>和<清平乐>,截止到目前为止,这两部剧在豆瓣分别为7.5分和7.9分,算 ...
- 爬取西刺网代理ip,并把其存放mysql数据库
需求: 获取西刺网代理ip信息,包括ip地址.端口号.ip类型 西刺网:http://www.xicidaili.com/nn/ 那,如何解决这个问题? 分析页面结构和url设计得知: 数据都在本页面 ...
- 爬取软考试题系列之ip自动代理
马上5月份有个软件专业等级考试,以下简称软考,为了更好的复习备考,我打算抓取www.rkpass.com网上的软考试题. 以上为背景. 很久没有更新博客园的博客了,所以之前的代码没有及时的贴出来,咱们 ...
- 百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制11。
1.POI爬取方法说明 1.1AK申请 登录百度账号,在百度地图开发者平台的API控制台申请一个服务端的ak,主要用到的是Place API.检校方式可设置成IP白名单,IP直接设置成了0.0.0.0 ...
- 【Python3爬虫】我爬取了七万条弹幕,看看RNG和SKT打得怎么样
一.写在前面 直播行业已经火热几年了,几个大平台也有了各自独特的“弹幕文化”,不过现在很多平台直播比赛时的弹幕都基本没法看的,主要是因为网络上的喷子还是挺多的,尤其是在观看比赛的时候,很多弹幕不是喷选 ...
- Python 爬取 11 万 Java 程序员信息竟有这些重大发现!
一提到程序猿,我们的脑子里就会出现这样的画面: 或者这样的画面: 心头萦绕的字眼是:秃头.猝死.眼镜.黑白 T 恤.钢铁直男-- 而真实的程序猿们,是每天要和无数数据,以及数十种编程语言打交道.上能手 ...
- python requests库爬取网页小实例:ip地址查询
ip地址查询的全代码: 智力使用ip183网站进行ip地址归属地的查询,我们在查询的过程是通过构造url进行查询的,将要查询的ip地址以参数的形式添加在ip183url后面即可. #ip地址查询的全代 ...
- [转] 分组排序取前N条记录以及生成自动数字序列,类似group by后 limit
前言: 同事的业务场景是,按照cid.author分组,再按照id倒叙,取出前2条记录出来. oracle里面可以通过row_number() OVER (PARTITIO ...
- HtmlUnit爬取Ajax动态生成的网页以及自动调用页面javascript函数
HtmlUnit官网的介绍: HtmlUnit是一款基于Java的没有图形界面的浏览器程序.它模仿HTML document并且提供API让开发人员像是在一个正常的浏览器上操作一样,获取网页内容,填充 ...
随机推荐
- maven:用appassembler-maven-plugin打包含有自定义目录的JAVA程序
问题说明: 用maven构建了一个项目,目录结构如下: appassemblerd的配置: <plugin> <groupId>org.codehaus.mojo</gr ...
- SharePoint 2007 Full Text Searching PowerShell and CS file content with SharePoint Search
1. Ensure your site or shared folder in one Content Source. 2. Add file types. 3. The second step in ...
- iOS9请求https问题-记录
iOS9 开始苹果将HTTP全改为HTTPS了,所以出现网络请求失败问题,解决办法: 1.改回HTTP: 在info.plist文件中添加一个Key:NSAppTransportSecurity(字典 ...
- iOS数字键盘自定义按键
UIKeyboardTypeNumberPad 数字键盘自定义按键 最近做一个搜索用户的功能,这里使用了UISearchBar.由于搜索的方式只有手机号码,所以这里的键盘要限制为数字输入,可以这么做: ...
- Objective-C Mojo和Django 对接
最近在做资料类app需要一个好的资源管理工具,excel在这方面非常好,不过能第一非常low,第二数据量一大查询就是个问题. 因此,我使用django做了个资源管理小工具.好处还是很明显的 (1)可以 ...
- Android Studio连接真机没反应?
刚好遇到这个问题,在网上百度了一下,看到有人分享了引起该问题的几个原因: 手机设置问题.开USB调试 方法: 手机设置 - 开发人员选项 - USB调试 - 勾选 数据线问题. 有的数据线只能用来充电 ...
- Play Framework 完整实现一个APP(九)
添加增删改查操作 1.开启CRUD Module 在/conf/application.conf 中添加 # Import the crud module module.crud=${play.pat ...
- SE_homework1(第一部分)
题目:写一个能自动生成小学四则运算题目的命令行"软件",分别满足下列各种需求.下面这些需求都可以用命令行参数的形式来指定: a.)除了整数以外,还支持真分数的运算.(例如1 ...
- PL/SQL重新编译包无反应
前几天碰到一个有趣的事情:早上同事执行一个包很久没有反应,就中断了执行,发邮件让我帮忙查看具体情况,我用PL/SQL Developer登录后,找到这个包的过程中发现这个包的图标有红色叉叉,也就是说这 ...
- javax.crypto.BadPaddingException: Given final block not properly padded 解决方法
下面的 Des 加密解密代码,在加密时正常,但是在解密是抛出错误: javax.crypto.BadPaddingException: Given final block not properly p ...