1. 程式人生 > >如何用python編寫火車搶票助手

如何用python編寫火車搶票助手

前幾天跟朋友說打算寫一個搶票助手,最後由於某些原因念頭打消了。

可就在昨天晚上,才隱約記起一年前的自己曾經說過:一年後我一定要寫一個12306的搶票助手!瞬間激情澎湃,甚至已經是快臨近凌晨時便開始動工,可天意不能違,12306晚上11點便開始維護,後續階段程式不得不暫停;只能今天繼續完成最後一部分,幸好自己進度還是可以的,剛剛debug完畢就給大家分享一下!

開頭肯定是老套路

首先我們要安裝python的編譯環境,推薦使用python3.6(本文章使用的是python3);

python下載安裝網址:https://www.python.org/

安裝python的第三方工具庫selenium

selenium是Web 應用程式自動化測試工具,可模擬人為操作實現自動化的強大的工具庫

第二步:

下載chrome自動化驅動,連結:

http://chromedriver.storage.googleapis.com/index.html

chrome自動化驅動與chrome瀏覽器版本是有相對應的版本;chrome瀏覽器最新版本對應驅動版本2.35

具體驅動與瀏覽器版本對映表檢視連結:

http://blog.csdn.net/huilan_same/article/details/51896672

第三步:進入主題,編寫程式碼

引入庫檔案

from selenium import
webdriver
from selenium.webdriver.common.keys import Keys
import time

編寫主要程式碼

us=input('請輸入12306賬號:')
pw=input('請輸入12306密碼:')
fromStation=input('請輸入出發站點:')
toStation=input('請輸入目的站點:')
date=input('請輸入出發時間(格式:2018-02-02):')
number=input('請輸入列車號(區別大小寫):')
passenger=input('請輸入乘車人姓名(格式:姓名(學生)或者姓名):')
driver=webdriver.Chrome()#載入chrome驅動

login(us,pw)#登入
query()#查詢
buyTicket()#搶票
confirm()#購票

乘車人姓名要預先在12306網址上存在,並且要按紅色方框內容填寫

編寫一個判斷xpath是否存在的函式XpathExist(driver,xpath)

def XpathExist(driver,xpath):
   """
   檢查xpath是否存在
   :param driver,xpath:
   :return:
   """

   try:
       driver.find_element_by_xpath(xpath)#若不存在會丟擲異常
       return True
   except:
       return False

編寫登入12306函式login(us,pw)

#12306登入
def login(us,pw):
   driver.get("https://kyfw.12306.cn/otn/login/init")#開啟網址
   username= driver.find_element_by_xpath('//*[@id="username"]')#獲取使用者名稱的位置
   password=driver.find_element_by_xpath('//*[@id="password"]')#獲取密碼的位置
   username.send_keys(us)#輸入使用者名稱
   password.send_keys(pw)#輸入密碼
   while True:
       #連結跳轉則,登入成功
       if driver.current_url=='https://kyfw.12306.cn/otn/index/initMy12306':
           break

編寫12306查詢函式query()

難點:主要就在輸入出發站跟目的站,12306反爬技術很強大,自己在這裡除錯了兩個小時,最後發現要先點選一下,再清除內容,再輸入內容,再按鍵盤Down鍵,最後再按tab鍵才可以;時間則要用js處理。

#12306查詢
def query():
   driver.get('https://kyfw.12306.cn/otn/leftTicket/init')#開啟網址
   fromStationText=driver.find_element_by_xpath('//*[@id="fromStationText"]')#獲取出發點的位置
   toStationText=driver.find_element_by_xpath('//*[@id="toStationText"]')#獲取目的地的位置
   #要先點選一下,在清楚輸入框的內容,再輸入內容,再按鍵盤Down鍵,最後再按tab鍵
   fromStationText.click()
   fromStationText.clear();
   fromStationText.send_keys(fromStation)
   fromStationText.send_keys(Keys.DOWN)
   fromStationText.send_keys(Keys.TAB)
   toStationText.click()
   toStationText.clear();
   toStationText.send_keys(toStation)
   toStationText.send_keys(Keys.DOWN)
   toStationText.send_keys(Keys.TAB)
      #用js輸入時間
   js="document.getElementById('train_date').value='"+date+"'"
   driver.execute_script(js)
   time.sleep(1)#等待1s
   while True:
       xpath='//*[@id="query_ticket"]'
       if XpathExist(driver,xpath):
           try:
               driver.find_element_by_xpath(xpath).click()#點選查詢按鈕
               print("查詢中...")
               break
           except:
               continue

搶票函式buyTicket()

#搶票
def buyTicket():
   while True:
       try:

           xpath="//a[text()='"+number+"']/../../../../../td[13]/a"
           if driver.current_url=='https://kyfw.12306.cn/otn/confirmPassenger/initDc':
               break
           if XpathExist(driver,xpath):
               order=driver.find_element_by_xpath(xpath)
               order.click()
               print("搶票中...")
           else:
               xpath='//*[@id="query_ticket"]'
               if XpathExist(driver,xpath):
                   try:
                       driver.find_element_by_xpath(xpath).click()
                   except:
                       print("重新點選")

       except:
           continue

確認購票confirm()

#確認購票
def confirm():
   while True:
       try:
           xpath='//*[@id="content_defaultwarningAlert_hearder"]/a'
           if XpathExist(driver,xpath):
               driver.find_element_by_xpath(xpath)
               print(driver.find_element_by_xpath(xpath))
           else:
               xpath='//label[text()="'+passenger+'"]'
               while True:
                   try:
                       driver.find_element_by_xpath(xpath).click()
                       break
                   except:
                       continue
               xpath='//*[@id="dialog_xsertcj_ok"]'
               if XpathExist(driver,xpath):
                   print("確認彈出視窗中...")
                   while True:
                       try:
                           driver.find_element_by_xpath(xpath).click()
                           break
                       except:
                           break
               xpath='//*[@id="content_defaultwarningAlert_title"]'
               if XpathExist(driver,xpath):
                    print('目前沒票')
               else:
                   print("點選成功")
                   driver.find_element_by_xpath('//*[@id="submitOrder_id"]').click()
                   while True:
                       try:
                           if driver.current_url!='https://kyfw.12306.cn/otn/confirmPassenger/initDc':
                               print("搶票成功,請及時付款")
                               break
                           xpath='//*[@id="orderResultInfo_id"]/div/span'
                           if XpathExist(driver,xpath):
                               print('搶票失敗')
                               break
                           driver.find_element_by_xpath('//*[@id="qr_submit_id"]').click()

                       except:
                           continue
                   break
       except:
           continue

由於想到這幾天大家要開始第一輪搶票模式,所以剛剛寫完的程式,沒有經過大量測試,我便匆匆忙忙釋出上來供大家分享;如果在使用中發現有bug,歡迎在文章留言,我會及時的處理!

為了不懂程式設計的小夥伴,同時我也對應釋出了可執行的exe檔案。