使用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[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(完全開源的),使之成為一款能夠提高生活便捷性的工具,新增很多新任務。比如:第二天要下雨或者下雪,發個郵件提醒,帶上雨傘…。好了到了放出原始碼的時間了。敬請期待下一篇!
簡單投票原始碼: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進行安裝。
相關文章
- python爬蟲實戰:爬取西刺代理的代理ip(二)Python爬蟲
- 爬蟲動態http代理ip有什麼功能爬蟲HTTP
- 爬蟲代理IP自動分配失敗的原因爬蟲
- Python 爬蟲IP代理池的實現Python爬蟲
- 【自動化】使用PlayWright+代理IP實現多環境隔離
- 實用爬蟲-02-爬蟲真正使用代理 ip爬蟲
- 動態ip代理教你:如何用爬蟲實現前端頁面渲染爬蟲前端
- 爬蟲使用代理防封IP爬蟲
- 爬蟲如何使用ip代理池爬蟲
- 爬蟲代理IP的使用技巧爬蟲
- 如何高效獲取大資料?動態ip代理:用爬蟲!大資料爬蟲
- JavaScript爬蟲程式實現自動化爬取tiktok資料教程JavaScript爬蟲
- 使用PHP實現動態代理IP的示例程式碼PHP
- 網路爬蟲怎麼使用ip代理爬蟲
- 爬蟲時代理ip應該具備什麼條件?爬蟲
- Python代理IP爬蟲的簡單使用Python爬蟲
- 爬蟲工作使用代理IP有哪些優勢?爬蟲
- 使用Go語言實現爬蟲功能Go爬蟲
- 使用Python爬蟲實現自動下載圖片Python爬蟲
- Vue實現自動觸發功能Vue
- 分散式爬蟲有哪些使用代理IP的方法?分散式爬蟲
- Golang實現的IP代理池Golang
- 爬蟲ip如何加入到程式碼裡實現自動化資料抓取爬蟲
- Python網路爬蟲進階:自動切換HTTP代理IP的應用Python爬蟲HTTP
- 使用WebDriverManager實現自動獲取瀏覽器驅動程式Web瀏覽器
- PHP+Ajax實現文章心情投票功能例項PHP
- 如何建立爬蟲代理ip池爬蟲
- 代理IP如何突破反爬蟲?爬蟲
- 爬蟲代理怎麼選ip爬蟲
- Python爬蟲動態ip代理防止被封的方法Python爬蟲
- jQuery實現使用者輸入自動完成功能jQuery
- vue swiper 實現滾動條功能(這個可當元件引入使用)Vue元件
- 代理ip的功能介紹
- 一篇瞭解怎麼使用爬蟲代理IP爬蟲
- 構建一個給爬蟲使用的代理IP池爬蟲
- 批處理實現自動ftp功能FTP
- 使用JavaCV實現讀取視訊資訊及自動擷取封面圖Java
- 使用代理IP的主要功能是什麼