(更新)python爬蟲實戰:模擬登錄12306(主要講解驗證碼的突破)
來自專欄數據結構與演算法:生物信息學必備知識
剛剛刷完慕課,寫完線代作業,現在是時候來一波驗證碼的突破測試了。在開始之前,我相信有很多朋友會問我:為什麼要選擇突破12306的驗證碼? 大家應該都知道,12306每天的火車票的數量都是有限的,如果有很多人都能夠通過爬蟲來進行搶票,那麼,讓那些不懂爬蟲的人應該怎麼辦呢? 所有12306的反爬措施肯定是很到位的,既然反爬很強,那麼也就是我們應該試著突破的對象。不因為別的,只是為了提高自己的技術,僅此而已。話不多說,下面進入正題。
大致思路是這樣的:
1.找到12306的登錄頁面,post請求一次,找到請求的真正url,以及提交給伺服器的數據data;
2.分析數據包data,找出需要提交的信息,然後再從上面的post請求中抓包分析,找到驗證碼的url;
3.找到提交data包的url,進行post請求,提交數據;
4.再次尋找所需要的驗證信息,(12306的驗證防護有3層,這篇文章,我們只講前面的部分)
首先,我們打開12306的登錄界面,F12,打開network選項,隨便輸入一個用戶名,密碼,和驗證碼,我們來看看會發出哪一些請求。
抓包分析可知,當點擊登錄的時候,瀏覽器發送了兩個http請求。點擊其中的一個,我們可以看見瀏覽器發出了一個post請求,而請求的真正的url是我紅線畫的url。
往下面看,可以發現,我們提交了一個data數據包,其中的login_site和rand都是定值,而answer則是驗證碼的解析度。這裡正是我們的突破口。
那麼,接下來的一步就是要找到驗證碼的解析度了,應該怎麼做呢?
首先,我們要找到請求驗證碼圖片的真實url,這裡需要注意的是:圖片的http請求和網頁主題的請求並不是同步的,所有的圖片信息都需要自己的url來進行請求。
顯然,剛剛抓包得到的第二個請求就是,驗證碼圖片的url。這是一個get請求,並不需要提交數據。
那麼。我們現在需要做的就是將這個圖片下載下來,然後通過畫圖工具,找到他的正確答案所對應的像素即可。 下面,我們開始寫代碼:(這裡只寫了主要的代碼,沒寫的大家自己添加,請看注釋)
check_res=my_session.get(ver_url)#得到驗證碼,並保存到本地#將驗證碼保存到本地with open(1.jpg,wb) as f: f.write(check_res.content)img=Image.open(1.jpg)img.show()#將圖片表示出來,用畫圖工具打開,然後就能看見像素ver=input("請輸入驗證碼>>>")#從驗證碼中得知的像素#構造表單,字典類型datas={"answer":ver,"login_site":"E","rand":"sjrand"}check_res=my_session.post(check_url,data=datas)print(check_res.text)
我們可以看一下輸出的內容是:
可以看見,現在已經模擬驗證碼輸入已經成功了。大家可以看下圖,當我們在網頁上將驗證碼輸入成功的時候,response的其實也就是這樣一串數字。
驗證碼這一部分已經ok了,下面就是要找到賬號和密碼提交的真實url
我們在瀏覽器中將,賬號,密碼,以及驗證碼全部輸入正確,點擊登錄時進行抓包分析:
可以看見,這次抓取的包就有很多了。在紅區的包中,進行查找,我們發現有一個post請求,提交了我們的賬號和密碼:(這裡時我隨便輸入的賬號和密碼,但是只要把驗證碼輸入正確之後,就會進行進行賬號和密碼的驗證,和上面說的把賬號和密碼,驗證碼全部輸入正確並不矛盾)
而很容易發現,這個post請求發送給給的是下圖url:
所以,下面我們就可以進行下一步了:對賬號和密碼進行一個驗證,代碼如下:
#抓包分析,得到提交賬號和密碼的urllogin_url="https://kyfw.12306.cn/passport/web/login"username=input("請輸入賬號:")password=input("請輸入密碼:")data={"username":username,"password":password,"appid":"otn"}login_res=my_session.post(login_url,data=data)print(login_res.text)
運行上面所有的代碼,結果如下:
現在,我們就yij將驗證碼的校驗給提交成功了,但是,這並不代表我們已經真正地登錄成功了,大家可以看見,在賬號密碼的驗證之後返回的response中,有一串名為uamtk的字元。、
實際上,這是我們下一步要使用的驗證信息。這是一個思路,大家可以接著自己去做,今天我就講這麼多。
源碼放在了我的的GitHub上,需要的朋友自取:
reBiocoder/python
更多優質內容,請關注微信公眾號:生物信息與python。
5月20日更新。
今天給大家更新一波。
在昨天的驗證碼和賬號密碼珀斯特之後,我們可以繼續分析url,很容易找到:還有兩個post請求。
這就是12306的第二層防護。我們看看其中一個post的數據包
可以看見他需要提供一個tk數據包,其實這就是我跟大家所說的上面登錄成功之後,utamk參數的作用,按照之前的分析,可以分析處需要提交的url,這裡直接上代碼:
login_res=my_session.post(login_url,data=data)print(login_res.text)data2={"appid":"otn"}Uamtk_res=my_session.post(Uamtk_url,data=data2)json=json.loads(Uamtk_res.text)umtk_id=json["newapptk"]print(umtk_id)data1={"tk": umtk_id}uamtk_res=my_session.post(uamtk_url,data=data1)print(uamtk_res.text)data3={"_json_att":""}use_res=my_session.post(user_url,data=data3)print(use_res.text)
最後的結果是這樣的:
需要源碼的朋友,可以去我的GitHub上下載
推薦閱讀: