現在生活中離不開各類的比賽,然而,各個比賽離不開投票,我們會清一色有時候找到我們的朋友在朋友圈發—幫寶貝投一票,幫某某老師,學生投一票。又或許你自己參加比賽,你在為你自己拉票。
作為一名程序員,你是否想為自己的生活開一點G呢?熟悉網絡請求的我們,應該從問題根源分析問題。對于一個投票的網站。大致分為兩類:
既然原理已經剖析完成,那么剩下的就是設計程序的問題了,對于一個點擊投票的事件,它的實質就是一次http(post)請求,然后后臺對數據進行更改。那么我們就可以對這個操作流程進行抓包,分析這個請求是那種類型,需要那些參數。然后根據這個請求模擬寫出請求。
然而最重要的就是ip代理,你要用代理的ip去訪問那個接口,讓對方以為是你代理的那個ip再對他訪問,所以你需要維護一個代理ip池。對于代理ip池,并不是什么高大上的東西,準確的來說就是一個集合中包含一些可用的ip,能夠供我使用。市面上也有很多出售代理ip,也不貴。我用的是蘑菇代理。
碰巧,最近參加的一個比賽就有拉票環節,如果人為手動拉票的話效率地下,并且你肯定也不會愿意天天去舔人家求情。那就自己分析一波!
找到url和幾個參數,就可以準備程序了。模擬請求了
因為這是多次請求,所以要考慮性能的問題和效率問題。不能讓異常漫天飛,中斷,ip白白浪費,或者苦苦等待吧。對于代理ip,各家賣的雖然有些差異但是大體相同。大致均為賣數量,然后每個ip從開始被用后能夠維持幾分鐘的使用。并且有的ip是不能用的,有的是高延遲的,這些在寫程序的時候都要過濾掉。這里面就要考慮下這個程序額設計。
import requestsimport randomimport timeimport threadingfrom queue import Queuedef loadip():##從代理ip中獲取ip 一次若干擴充到queue中 url2 = 'http://piping.mogumiao.com/proxy/api/get_ip_al?appKey=f16367295e284173ae450f&count=20&expiryDate=0&format=1&newLine=2' req = requests.get(url2) date = req.json() if(date['code'])!='3001': ipdate2 = date['msg'] for va in ipdate2: que.put(va)class downspider(threading.Thread):##線程類 def __init__(self, threadname, que): threading.Thread.__init__(self) self.threadname = threadname self.que = que def run(self): print('start thread' + self.threadname) while True: try: toupiaospider(que,self.threadname)##投票函數 except Exception as e: print(e,'888') breakdef getproxies():#獲取ip 拼接成需要的代理格式 b=que.get() d = '%s:%s' % (b['ip'], b['port']) global proxies proxies['http'] = d return proxiesdef toupiaospider(que,threadname): if (que.qsize() < 15): # 拓展ip池 loadip() proxies2=getproxies() for i in range(0,5): try: #formData['times']=i req = requests.post(url, headers=header, data=formData, proxies=proxies2, timeout=1.5) res = req.json() if res['res']==2001 or req.status_code!=200: continue print(threadname,proxies2['http'],res,que.qsize()) except Exception as e: print('errror',e)if __name__ == '__main__': proxies = {'http': ''} stadus = 0 que = Queue() threads=[]#線程 url='http://yunxin.163.com/api/vote/update' header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'} formData = { 'Referer':'http://yunxin.163.com/promotion/minichallenge/gallery?from=groupmessage&isappinstalled=0', 'id':'17', 'times':'1', 'activity':'minichallenge1' } proxies = {'http': '182.247.92.99:21136', } loadip() time.sleep(5) ##線程數組 ->啟動 ——>等待join threadList = ['thread-1','thread-2','thread-3','thread-4','thread-4','thread-5'] for j in threadList: thread = downspider(j, que) thread.start() threads.append(thread) for t in threads: t.join()
結果
在java中比較棘手的就是java自身對json和http請求的處理不太方便,需要借助第三方jar,并且一些操作稍顯的繁瑣。
首先java要弄清幾點:
針對上面的問題。寫了個demo測試進行預備,對于獲取ip的api,大致這種格式
首先你要下載fastjson和jsoup的jar包?;蛘呒尤雖aven依賴。(可在maven官網下jar包)
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup --> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.12.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency>
然后寫個demo跑一下
package com.bigsai;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class test2 { static int va=1; public static void main(String[] args) { String ti="{"code":"0","msg":[{"port":"40034","ip":"114.237.64.247"},{"port":"33257","ip":"223.240.210.250"},{"port":"39618","ip":"113.101.255.11"},{"port":"43151","ip":"183.135.106.62"},{"port":"41795","ip":"182.108.44.227"}]}"; JSONObject jsonObject= JSON.parseobject(ti); String code=(String) jsonObject.get("code"); JSONArray jsonArray=jsonObject.getJSONArray("msg"); for(Object te:jsonArray) { JSONObject team=(JSONObject) te; String ip=team.getString("ip"); int port=team.getInteger("port"); System.out.println(team+" "+ip+" "+port); } ExecutorService ex= Executors.newFixedThreadPool(10); for(int i=0;i<200;i++) { threadtest threadtest=new threadtest(); ex.execute(threadtest); } ex.shutdown(); } static synchronized void addva()//去掉注釋試試 { va++; try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" "+va); } static class threadtest implements Runnable{ @Override public void run() { addva(); } }}
觀察結果。打印,這些邊角問題你就明白了。就可以設計java程序了。
package com.bigsai;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import org.jsoup.Connection;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import java.io.IOException;import java.net.InetSocketAddress;import java.net.Proxy;import java.util.ArrayDeque;import java.util.HashMap;import java.util.Map;import java.util.Queue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class wangyi { //改成你自己的token已經被我改了 static String ipurl="http://piping.mogumiao.com/proxy/api/get_ip_al?appKey=f16367295e284173ae3&count=20&expiryDate=0&format=1&newLine=2"; /** * java的多線程和python略有不同,但也可以改成相似的 * py是5個線程每個線程死循環任務,而java用線程池每個線程一個任務,只不過new了很多對象 * @param args */ static Queue<proxynode> q1; public static void main(String[] args) { q1=new ArrayDeque();//隊列存放結構體 ip和port ExecutorService ex= Executors.newFixedThreadPool(10); for(int i=0;i<200;i++) { try { Proxy proxy=getproxies(q1);//獲得代理ip vote vote=new vote(proxy); ex.execute(vote); } catch (Exception e) {e.printStackTrace();} } ex.shutdown(); } static synchronized Proxy getproxies(Queue<proxynode> q1) throws IOException//上鎖獲得代理,因為ip只用一次,也可使用自帶的線程安全隊列 { if(q1.size()<15)//擴充ip池 { String jsonva=Jsoup.connect(ipurl).timeout(2500).get().text(); JSONObject jsonObject= JSON.parseObject(jsonva); String code=(String) jsonObject.get("code");//狀態嗎 if (code.equals("0")) {//正常返回接口 JSONArray jsonArray = jsonObject.getJSONArray("msg"); for (Object jsonobj: jsonArray) { JSONObject team = (JSONObject) jsonobj; String ip = team.getString("ip"); int port = team.getInteger("port"); proxynode node=new proxynode(ip,port); q1.add(node); } } else return null; } proxynode proxynode=q1.poll(); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxynode.ip, proxynode.port)); return proxy; } static class proxynode//一個node儲存ip和端口 { String ip; int port; proxynode(String ip,int port) { this.ip=ip; this.port=port; } } static class vote implements Runnable{ Proxy proxy; vote(Proxy proxy) { this.proxy=proxy; } public void dovote() throws IOException { //Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("host", 8888)); try { Connection connect = Jsoup.connect("http://yunxin.163.com/api/vote/update").timeout(2000); Map<String,String>date=new HashMap<String, String>(); date.put("id","17"); date.put("times","1"); date.put("activity","minichallenge1"); date.put("Referer","http://yunxin.163.com/promotion/minichallenge/gallery?from=groupmessage&isappinstalled=0"); date.put("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"); connect.data(date); connect.ignoreContentType(true); connect.proxy(proxy); Document doc=connect.post(); System.out.println(Thread.currentThread().getName()+" "+proxy.address()+" "+doc.text()); } catch (Exception e) { System.out.println(e.toString()); } } public void run() { try { for(int i=0;i<5;i++) { dovote(); } } catch (IOException e) { e.printStackTrace(); } } }}
結果
在寫爬蟲還是python方便和簡單。因為py對json支持較好(字典),而java強對象類型語法要求較嚴。但是在多線程方面java肯定是秒殺py的。因為py的多線程是(假)多線程。想提高速度的可以研究多進程。
這類問題本質不難的,做過一次就很簡單了。這只是其中一種案例。提供一些思想和解決思路。遇到不同的問題可能需要不同的結構,方式去解決,這就需要融匯貫通。
如果有錯誤,請大佬指正。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
如何創建csv文件?1.首先,打開excel辦公軟件,通過CTRL N新建一個工作簿..2.編輯現有工作簿中的表格,編輯后按ctrl s打開“另存為”窗口。3.指定保存路徑,更改文件名,并選擇文件類型。4.在文件類型中,選擇*。csv格式,選擇完成,然后單擊保存。5.閱讀彈出窗口中的提示并單擊是,這意味著csv文件已成功創建。超大的csv文件怎樣用excel打開???首先,創建一個新的Excel并打...
當然是北京可以養金毛嗎?。金毛有以下優點,適合飼養。1.金毛是一種溫和的犬種。它是三種非攻擊性犬種之一。它很溫柔,對人類很友好,喜歡和人玩,平時也很溫柔。(但是唐 我不認為它 真的沒有攻擊性。)2,金毛顏值高,小時候特別軟萌,長大后很帥,笑起來有一種別扭的感覺,很有治愈力。3.金毛 s智商高。據說金毛 s的智商在狗界排第四,可見他很聰明。平時稍加訓練,金毛就能很快理解他的主人 s的話,學好他的技術...
什么叫RSS源?RSS為Really Simple Syndication(簡易工具供稿)的縮寫,是某一站點用處和其它站點之間鏈接共享內容的一種簡易,也叫聚合體內容。RSS,原意是把網站內容如標題、鏈接、部分內文甚至還加番裝換為可向外延伸標示語言(XML:eXtensible MarkupLanguage)的格式Reeder 4,你認為它依然是最好的RSS閱讀器嗎?“頭條”本身,當然是三個浩大的R...