當前位置:
首頁 > 最新 > Python大牛實現12306全自動搶票系統,學完後春運回家搶票無憂

Python大牛實現12306全自動搶票系統,學完後春運回家搶票無憂

隨著2018年春節的腳步日益臨近,歸心似箭的人們都希望能儘快趕回家中。中國人回家過年,是每個人一年中最重要的事,無論你離家遠近。在所有的交通工具中,承擔著最大客流量的交通工具,毫無疑問是火車。中國龐大的人口與密布的中中國鐵路網緊密相連,每一個歸家遊子的回家欲求逐漸匯聚成春運大潮,成為每年春節都避免不了的現象。另據TechWeb報道 1月8日消息稱,2018年春運從2月1日開始至3月12日結束,共計40天。國家發展改革委網站今日發布「關於全力做好2018年春運工作的意見」(簡稱「意見」),要求鐵路進一步擴充互聯網售票系統處理能力,豐富支付手段,提升購票體驗。相信每一位遊子都有在12306上購買車票的經歷,也相信不少購票者都因在12306上搶票而對該網站的「任性」印象深刻。

今天,小編就向大家簡單介紹一下,如何通過AI時代的編程利器Python在12306上優雅地搶票。

首先在買票前我們需要先確認是否有票,那麼進行正常的查票,打開12306查票網站https://kyfw.12306.cn/otn/leftTicket/init 輸入出發地和目的地進行搜索。

圖1

因為該請求是採用的js中ajax非同步請求的方式動態載入的,並不包含在源代碼裡面,所以我們只能夠通過抓包的方式來查看瀏覽器與伺服器的數據交互情況,通過使用谷歌瀏覽器的開發者工具,其打開方式可以是快捷鍵F12或shift+ctrl+i。通過元素選項卡,查看相應的網頁元素。

圖2

選中network選項,此時只要是瀏覽器和伺服器發生數據交互都會在下面列表框顯示出來,我們再次點擊查詢按鈕。

圖3

從返回結果看,我們可以看到列表中出現了兩個請求,下面我們就根據這兩個返回值來分析判斷哪個請求才是真正獲取到車次相關數據的請求,以便我們用Python來模擬瀏覽器操作。

第一次請求:

圖4

很明顯第一次請求返回的值沒有我們需要的車次信息。

第二次請求:

圖5

第二次請求裡面數據比較多,雖然我們暫時還沒看到車次信息,但是我們發現這個列表的值裡面有13個元素,而我們搜索出來的從合肥到杭州的車輛也是13條數據,所以這兩者肯定有一定關係,那麼我們先用Python來獲取到這些數據再進行下一步分析:

# -*- coding: utf-8 -*-

import urllib2

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

def getList():

req = urllib2.Request( "https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-09&leftTicketDTO.from_station=HFH&leftTicketDTO.to_station=HZH&purpose_codes=ADULT")

req.add_header( "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

html = urllib2.urlopen(req).read()

return html

print getList()

圖6

首先定義一個函數來獲取車次列表信息:

從抓包數據中獲取到該請求的url:https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-09&leftTicketDTO.from_station=HFH&leftTicketDTO.to_station=HZH&purpose_codes=ADULT

為了防止被12306檢測到屏蔽我們的請求那麼我們可以簡單的增加個頭信息來模擬瀏覽器的請求。

req. add_header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

其中的:

ssl. _create _default_https _context = ssl. _create _unverified _context

是因為12306採用的是https協議,而ssl證書是它自己做的並沒有得到瀏覽器的認可,所以Python默認是不會請求不受信任的證書的網站的,我們可以通過這行代碼來關閉掉證書的驗證

那麼我們先來看看能不能正常獲取到我們想要的信息 :

圖7

事實證明我們的操作沒有問題,接下來先拿到包含有13條數據的這個列表再說。

返回的數據是json格式,但是Python標準數據類型中沒有json這個類型,所以對於Python而言它就是個字元串,如果要非常方便的操作這個json我們就可以藉助Python中的json這個包來把json這個字元串變成dict類型,然後通過dict的鍵值對操作方法把列表取出來並進行返回。

最終返回的是一個list數據,我們先把這個數據for出來再看看每一條數據都有些什麼東西:

for出來之後我們先來看看第一條數據是什麼樣的:

|預訂|4e0000G59604|G596|WHN|HGH|ENH|HGH|16:42|19:22|02:40|Y|X9nNIopI6veiH0N47EFP9D9VoNOalcBzrKiqWVGBi77NXE4%2F|20180109|3|N2|04|11|1|0|||||||||||2|無|2||O0M090|OM9|0

其實我們稍微留一下就會發現裡面有包含G596,16:42,02:40,無這樣的車次信息的,只不過看起來比較亂,但是他們都有一個特點,每個數據都是由|這個符號分開的,所以我們可以通過用|分割看看能發現什麼呢?

for i in getList():

for n in i. split("|"):

print n

break

圖8

可以看到所有的值都列印出來了,我們再在前面加上一個序號就能清楚到看到每個序號所對應的值到底是什麼了,比如有輛火車商務座特等座還剩3張票,軟卧沒有剩票,顯示無,那我們就查看哪個序號對應的值是「3」哪個序號對應的值是「無」就搞清楚了哪個序號是代表什麼座次或者其他參數了。

圖9

到了這裡用的這個函數只能夠獲取到從合肥到杭州的數據,而別人不一定是買這個方向的火車,所以我們還得搞清楚請求的url當中的出發站和到達站的值是怎麼來的。

url:https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2018-01-09&leftTicketDTO.from_station=HFH&leftTicketDTO.to_station=HZH&purpose_codes=ADULT

先找到出發站和到達站的參數分別是:leftTicketDTO.from_station=HFH&leftTicketDTO.to_station=HZH

然而通過查找和分析我並沒有發現這兩個參數有規律,那麼也就是說這兩個值是在之前的請求裡面就已經獲取到了的,通過檢查網頁源代碼沒有找到,那麼又只能通過抓包的方式來找。

在抓包過程中找到了一個包的返回值是附帶有各城市的代號的,url如下:

https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9043

圖10

然後我們通過把參數做成通過輸入出發城市和到達城市就可以直接在這個數據裡面匹配到相應的城市代號,代碼如下:

圖11

這樣就已經能夠通過輸入時間,城市獲取相應的車次信息了 。

圖12

到這裡,僅僅完成整個搶票環節的一環而已,同時再結合登錄,購票等流程,才算基本完成整個流程,由於整個過程較為複雜而篇幅有限,所以小編這裡就先簡單介紹到這裡,希望給還在為春運購票而煩惱的你提供些許思路。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

TAG:Python |