前言
現在部分比賽為了推廣贊助商或者比賽本身,需要參賽隊伍進行網上拉票,甚至票數還會占一定比例的成績。因此,刷票也就應運而生了。此次我們團隊參加一個比賽,就需要網上投票決出前幾名,作為一位技術人員,當然是得“解決”技術能解決的問題嘛,所以就寫了個刷票插件來刷一刷。
原理
刷票的原理很簡單,就是相當于模擬人登錄網站去投票,只是把這個過程程序化,讓程序代替人到網站去投票。具體一點說把,首先是客戶端(我們)發出請求(Request)給服務端(投票網站),跟他們說,我們需要看他們網站的信息,然后服務端就會回復(Respose)我們,我們再把填好的表單發給他們(Request),他們收到后就會回復我們(Respose)。
主要內容
- 分析網站
- 表單提交
- 構造代理IP池
1. 分析網站
由于每個網站需要提交的信息都不一樣,那么首先我們需要對目標網站進行相對應的分析,找出他們的表單接口(也就是URL或者叫網址)以及我們需要提交的信息。
1.1 收集信息
首先我們登錄目標網站
使用F12,打開審核元素,點擊Network,真實地進行一次表單提交
框住的兩個內容就是我們需要知道的一部分表單信息
- Request URL:請求網址,我們提交的信息就是傳到這個url里面去
- Request method:請求方法,我們提交的方法
下面有兩個框分別框住兩個不同的信息區域,具體有什么用呢?下面就來詳細解釋一下這個
- Request Headers:請求頭,當我們訪問網站的時候,我們都需要提交一個請求頭過去,以證明我們不是爬蟲,而是真實的訪問,所以我們要把這個拿到,以便假裝我們不是爬蟲。
- From Data:這就是我們要提交的數據了,現在提交的數據都是以json格式提交,按照這些信息寫好我們需要提交的json數據就好
以上就是需要獲得的基本信息,根據這些信息我們就可以編寫刷票插件了,但作為一個對自身有高標準嚴要求的程序員來說,僅僅這樣就足夠嗎?當然不會啦,我們得找一找這個提交過程有沒有什么漏洞。
怎么找?分析源代碼,找了找,果真還讓我找到了!
看出什么沒有,它這里有兩個致命的漏洞:
- 它允許提交3支或3支以上的隊伍,并且沒有限制最大數量,只限制了最少數量。
- 它沒有進行相同數據的篩選。
意思就是說,我們可以一次提交幾百上千個,甚至上萬個==相同的==數據。但我會這么做嗎?考慮到后果的話肯定不會,因為沒有人可以在很短時間內投很多票,要是他們追查起來,那發現還不簡單?畢竟我們是在模擬真實投票嘛,所以就投3票給自己好了,隱藏功與名。
2. 表單提交
好了,既然把收集到的數據都整理好了,那么就開始寫代碼進行表單提交了。
2.1 運用到的庫
- requests:非常好用的第三方庫,用于表單提交
把它看一遍,所有操作就沒問題了,下面就來寫代碼吧!
2.2 構造表單信息
拿著這個代碼就能去投票啦,開不開心?
# 請求頭信息
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip',
'Accept-Language': 'zh-CN',
'Connection': 'keep-alive',
'Content-Length': '16',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'www.dingnf.com',
'Origin': 'http://www.dingnf.com',
'Referer': 'http://www.dingnf.com/active/wxws_s',
'User-Agent': 'Mozilla/4.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.3029.110 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'
}
# post表單網址
url = "http://www.dingnf.com/active/wxws_t"
params = {'ids': ['22', '22', '22']}
r = requests.post(url=url, data=params, headers=headers, proxies=proxies)
突然發現問題來了,只能提交一次!這是為什么?
3. 構造代理IP池
大部分投票網站都會記錄投票的IP地址,避免同一個IP多次投票,那怎么辦?我們能模仿真實投票,還換不了IP地址?換IP地址是可以的,不過比較麻煩,我們有一種更加簡便的方法:使用代理服務器去爬去某個網站的內容,那對方網站上顯示的就不是我們真實的IP地址了,而是代理服務器的IP地址,在python中,使用代理服務器設置很簡單。
3.1 找到代理IP
這里推薦西刺免費代理IP,西刺,值得你擁有
使用API可以快速獲得我們需要的IP地址,當然,我們也可以做個爬蟲,去爬它網站上的URL,這里就不展開說了。
3.2 構造IP代理容器
由于從API上獲得的數據多出一些換行符和回車符,不利于直接提取IP地址,所以就先用正則表達式直接提取需要的信息,再寫進列表里面,方便之后讀取。
def WriteIPadress():
all_url = [] # 存儲IP地址的容器
# 代理IP的網址
url = "http://api.xicidaili.com/free2016.txt"
r = requests.get(url=url)
all_url = re.findall("\d+\.\d+\.\d+\.\d+\:\d+",r.text)
with open("D:\\code\\python\\new\\Brush ticket\\IP.txt",'w') as f:
for i in all_url:
f.write(i)
f.write('\n')
return all_url
4. 主函數
count = 0 # 計數器
while count < 4000:
all_url = WriteIPadress()
for i in all_url:
proxies = {"http": i}
try:
r = requests.post(url=url, data=params, headers=headers, proxies=proxies)
if(r.json()['flag'] == True):
count += 1
print("成功投票%d次!" % (count))
print(r.json())
except Exception as reason:
print("錯誤原因是:",reason)
由于某些IP地址是存在問題的,所以需要設置異常處理,以便讓程序能夠正常運行,而API的數據每15分鐘更新一次,我們每跑完一遍列表的時間也差不多,因此也就不做其他處理了。
運行日志
源代碼
個人博客,最新更新的文章都發在這,歡迎關注:https://yeah-kun.github.io/