天天看點

使用Python和Splinter實作12306火車票查詢與搶票

有一段時間沒有使用Python了,前幾天經朋友提起一篇關于用Python實作搶火車票的文章,百度了實作搶火車票的技術細節,網上卻有不少資料,也不是新鮮的東西。在了解了一些技術手段,閱讀了一些大神的博文後,也嘗試實作了一下,代碼寫得粗糙,純當娛樂,本文在Windows系統下完成。需要提到的是,搶票過程中的驗證碼部分隻能手動完成。

首先,我需要的工具群組件有:

  • Chrome浏覽器
  • 浏覽器驅動ChromeDriver
  • Python 3.5
  • Web應用測試工具Splinter

Chrome浏覽器可自行下載下傳,其浏覽器驅動ChromeDriver可在以下連結找到:http://chromedriver.storage.googleapis.com/index.html?path=2.20/

使用Python和Splinter實作12306火車票查詢與搶票

在官網下載下傳Python,選擇Windows x86 executable installer,安裝過程中會一同安裝IDLE、pip等等,可勾選選項添加Python為環境變量(在Windows cmd下運作Python,需要設定環境變量)。安裝完成後,執行:pip install splinter安裝Splinter即可。

使用Python和Splinter實作12306火車票查詢與搶票

基本的配置已完成,測試一下,cmd下運作Python,分别鍵入以下指令:

>>> from splinter.browser import Browser
>>> b = Browser(driver_name="chrome")
>>> b.visit("http://www.qq.com")           
使用Python和Splinter實作12306火車票查詢與搶票

可以建立一個基本檔案,寫入以上三句語句:

使用Python和Splinter實作12306火車票查詢與搶票

在執行後續操作時,需要用到Google Chrome開發者工具,按“F12”或“shift+ctrl+i”呼出。找到Elements頁籤,這裡記錄了目前頁面每個元素的資訊,如以下的搜尋欄和“百度一下”按鍵,可選擇想要檢視的網頁要素或位置,Elements會跳轉到相應的實作代碼。

使用Python和Splinter實作12306火車票查詢與搶票
使用Python和Splinter實作12306火車票查詢與搶票

搜尋欄的name = “wd”,”百度一下“按鍵的id = “su”,在得到這一資訊後,可以執行以下三步操作:

1. 輸入:

b.fill("wd", "splinter")

即可在搜尋欄搜尋splinter。

2. 輸入:

button = b.find_by_value(u"百度一下")

尋找該按鍵

3. 輸入:

button.click()

點選該按鍵

更多操作,可參考splinter的官方文檔。。。

下面開始進入12306的網址進行操作:

使用Python和Splinter實作12306火車票查詢與搶票

類似于在百度頁面的操作,在使用者名和密碼欄目中輸入個人資訊:

b.find_by_text(u"登入").click()
b.fill("loginUserDTO.user_name",username) # username部分輸入自己的賬号
b.fill("userDTO.password",passwd) # passwd部分輸入賬号密碼           
使用Python和Splinter實作12306火車票查詢與搶票

之是以說是半自動搶票,是因為在搶票之前需要手動搜集一些資訊,比如手動選擇一次出發地點、日期和到達地點等資訊,然後F12打開開發者工具,點選Resources,找到cookies選項,可以看到下圖所示的内容:

使用Python和Splinter實作12306火車票查詢與搶票

通過cookies可以看到手動選擇的出發地點

_jc_save_fromStation

及其值value,還有出發日期

_jc_save_fromData

及目的地

_jc_save_toStation

等内容。其中每個地名會對應一個獨占的value,是以如果你是要刷從北京去上海的車票,需要手動先查查北京和上海分别對應的value值,并記錄下來,後面有用。

接下來,執行以下指令,添加cookies資訊:

b.cookies.add({"_jc_save_fromDate":"2016-01-18"}) # 此處添加出發日期
b.cookies.add({"_jc_save_fromStation":"此處添加各地名所對應的value值"}) # 此處添加出發地
b.cookies.add({u'_jc_save_toStation':'此處添加各地名所對應的value值'}) # 此處添加目的地           
使用Python和Splinter實作12306火車票查詢與搶票

之後,再次重新整理頁面時,可以發現浏覽器會自動填寫之前手動填寫的内容,在執行刷票時,這無疑節省了很多時間:

使用Python和Splinter實作12306火車票查詢與搶票

後續的操作也不多了,reload頁面,然後尋找頁面内的”查詢“按鈕并點選,再尋找可點選的”預訂“按鈕,這裡有一個問題是可能出現多個班次,是以如果要操作代碼去點選某個班次的”預訂“按鈕,也不困難,使用以下指令即可:

b.find_by_text(u"查詢").click()
b.find_by_text(u"預訂")[1].click() # 下标1表示買的是可選班次的第二班車           
使用Python和Splinter實作12306火車票查詢與搶票

最後執行幾句指令自動選取購票人,然後再手動選取驗證碼圖檔,即可完成搶票(驗證碼還是一道不可逾越的鴻溝)。

以上是整個流程,在完整代碼中,隻需再加入一些基本的循環和判斷,所有這些加起來不到100行。整個過程手動輸入驗證碼是不可避免的,除非擁有驗證碼的資料庫,然後在這基礎上做一些圖像識别的算法,但這會是一個工作量較大的任務。

參考連結:http://www.jb51.net/article/75992.htm