Python實現(xiàn)12306自動搶火車票功能
大家有沒有這種感覺,一到國慶、春節(jié)這種長假,搶火車票就非常困難?各大互聯(lián)網(wǎng)公司都推出搶票服務,只要加錢給服務費就可以增加搶到票的幾率。有些火車票代售網(wǎng)點和一些加速買票軟件,說你只要給100元服務費就可以優(yōu)先幫忙搶到票。本文和你一起探索搶票軟件背后的原理。
一、效果展示
在正式進入代碼講解之前,先來看下本文的實現(xiàn)效果。
如果不是為了演示效果,直接在最后確定階段加一個延時點擊確定,應該不到45秒可以鎖定一張票,只要在30分鐘之內(nèi)付款即可。
二、代碼詳解
本小節(jié)會詳細解鎖搶票軟件是如何模擬登錄網(wǎng)站,進行自動買票的。為了更清晰地給大家展示,部分代碼沒有寫成函數(shù),直接裸代碼運行,讓需要買票的朋友可以自己應用軟件進行購票。
1 導入庫
首先導入本文需要加載的庫,如果你有些庫還沒有安裝,導致運行代碼時報錯,可以在Anaconda Prompt中用pip方法安裝。
import json import time from captcha import * from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import wait from selenium.webdriver.common.keys import Keys from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support import expected_conditions as EC #導入庫
2 確定好購票基本信息
導入庫后,在python代碼中填寫你購票的基本信息。
purpose = 'ADULT' #購買成人票,如果是學生票,需調(diào)整代碼 names = ['謝朝陽'] #填寫購票人姓名 date = '2021-09-21' #填寫購票日期 start_station = '深圳' #購票出發(fā)站 end_station = '長沙南' #購票目的站 password = '11234567xyz' #登錄12306的秘密 username ='xiezhaoyang122700' #登錄12306的賬號 trains = ['G1004', 'G80', 'G6028', 'G6182', 'G6016'] #你想買的班次 #填寫基本信息
本文預訂的是2021年9月21日從深圳到長沙南的高鐵票,你可以根據(jù)自己的實際需要進行調(diào)整。由于有些班次的時間過早或過晚,買了也很不方便,所以可以在trains中挑選出你滿意的班次進行購票。在這里需要提醒大家,我之前在嘗試代碼時碰到的坑,那就是時間中如果有個位數(shù)要在前面填0。比如2021年9月2日,你在填寫購票日期date時要寫成'2021-09-02',否則在運行代碼時日期總是填不進去。
3 登錄12306
確定好購票的基本信息后,就可以應用python模擬登錄12306了,代碼如下:
options = webdriver.ChromeOptions() options.add_argument("--disable-blink-features=AutomationControlled") browser = webdriver.Chrome(options=options) browser.maximize_window() login_url = 'https://kyfw.12306.cn/otn/resources/login.html' #ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init' browser.get(login_url) time.sleep(0.5) wait.WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.CLASS_NAME,'login-hd-account'))).click() input_name = browser.find_element_by_id('J-userName') input_pd = browser.find_element_by_id('J-password') input_name.send_keys(username) input_pd.send_keys(password) login = browser.find_element_by_id('J-login') login.click() #登錄12306
整體思路是:?
1.應用python模擬調(diào)用google瀏覽器;
2.輸入12306網(wǎng)址;
3.等網(wǎng)頁加載完全后點擊賬戶密碼登錄;
4.找到賬號密碼的id,把賬戶密碼信息填充進去;
5.找到登錄id,模擬點擊登錄按鈕。
在這一小節(jié)中要注意兩個點。
一、要在python安裝目錄中放和google版本匹配的chromedriver,供python調(diào)用。
二、要學會找填寫賬戶密碼信息的id。
首先,在google瀏覽器中輸入12306登錄網(wǎng)址:
https://kyfw.12306.cn/otn/resources/login.html
接著點擊賬戶密碼登錄,會出現(xiàn)如下界面:
然后點擊紅框中的三個點,找到更多工具,點擊開發(fā)者工具,會出現(xiàn)如下界面:
點擊紅框中的箭頭,把鼠標移動到賬戶框上去,就會出現(xiàn)如下界面:
右邊變灰的框里就會出現(xiàn)對應的id,點擊賬號框,再把鼠標移動到右邊變灰的字符上去,點擊右鍵,會出現(xiàn)copy element的選項,復制下來即可。
<input type="text" class="input" id="J-userName" placeholder="用戶名/郵箱/手機號" style="height: 44px; line-height: 44px; outline: black 0px;" aria-label="請輸入用戶名/郵箱/手機號" title="請輸入用戶名/郵箱/手機號">
發(fā)現(xiàn)了嗎?源代碼input_name中要填寫的browser.find_element_by_id('J-userName')
內(nèi)容,即為id="J-userName"
中的信息。
4 模擬滑動滑塊
輸入完用戶名和密碼,點擊立即登錄后,會出現(xiàn)如下滑塊驗證要求。
運行如下代碼即可拖動滑塊進行驗證。
browser.implicitly_wait(5) print('=====開始處理滑動驗證碼=====') track = [300, 400, 500] for i in track: try: btn = browser.find_element_by_xpath('//*[@id="nc_1__scale_text"]/span') ActionChains(browser).drag_and_drop_by_offset(btn,i,0).perform() except: time.sleep(2) #拉動滑塊驗證
其中,browser.implicitly_wait(5)
表示隱性等待5秒,track中放的是滑塊拉動的距離。
5 處理疫情特殊要求
完成滑塊驗證要求后,會出現(xiàn)如下疫情特殊要求提示:
用如下代碼點擊確認即可。
browser.implicitly_wait(5) browser.find_element_by_xpath('/html/body/div[5]/div[2]/div[3]/a').click() time.sleep(2) #疫情特殊要求
browser.find_element_by_xpath
和id的區(qū)別是,在右鍵復制時要copy XPath或copy full XPath。
6 點擊購票并填寫出發(fā)地、目的地、出發(fā)時間
接下來是選擇買票,并將出發(fā)地、目的地、出發(fā)時間等信息填寫進去。
browser.find_element_by_xpath('//*[@id="J-chepiao"]/a').click() browser.find_element_by_xpath('//*[@id="megamenu-3"]/div[1]/ul/li[1]/a').click() browser.find_element_by_xpath('//*[@id="qd_closeDefaultWarningWindowDialog_id"]').click() #選擇買票 def input_info(): print('=====開始買票=====') from_station = browser.find_element_by_xpath('//*[@id="fromStationText"]') from_station.send_keys(Keys.ENTER) from_station.send_keys(Keys.CONTROL, 'a') from_station.send_keys(start_station, Keys.ENTER) browser.implicitly_wait(5) to_station = browser.find_element_by_xpath('//*[@id="toStationText"]') to_station.send_keys(Keys.ENTER) to_station.send_keys(Keys.CONTROL, 'a') to_station.send_keys(end_station, Keys.ENTER) browser.implicitly_wait(5) start_date = browser.find_element_by_xpath('//*[@id="train_date"]') start_date.send_keys(Keys.ENTER) start_date.send_keys(Keys.CONTROL, 'a') start_date.send_keys(Keys.CONTROL, 'x') start_date.send_keys(date, Keys.ENTER) browser.implicitly_wait(5) wait.WebDriverWait(browser, 3).until(EC.element_to_be_clickable((By.ID,'query_ticket'))).click() input_info() input_info() #將出發(fā)地、目的地、出發(fā)日期填進去
得到結(jié)果如下:
這里需要注意的是我調(diào)用了兩遍input_info函數(shù),因為12306可能采取了一些反爬措施,一遍輸入進去后查不出東西,顯示為灰色。
7 鎖定車票
最后是依次查找trains中的車次是否有票,有的話點擊購買鎖定車票。
trList = browser.find_elements_by_xpath(".//tbody[@id='queryLeftTable']/tr[not(@datatran)]") for tr in trList: trainNum = tr.find_element_by_class_name("number").text if trainNum in trains: leftTicket = tr.find_element_by_xpath(".//td[4]").text print('leftTicket', leftTicket) if leftTicket == '有' or leftTicket.isdigit(): orderBtn = tr.find_element_by_class_name("btn72") orderBtn.click() browser.implicitly_wait(5) passengerLabels = browser.find_elements_by_xpath(".//ul[@id='normal_passenger_id']/li/label") for passengerLabel in passengerLabels: name = passengerLabel.text if name in names: passengerLabel.click() browser.implicitly_wait(20) # 獲取提交按鈕 submitBtn = browser.find_element_by_id("submitOrder_id") submitBtn.click() browser.implicitly_wait(20) confirmBtn = browser.find_element_by_id("qr_submit_id") confirmBtn.click() time.sleep(2) browser.implicitly_wait(20) confirmBtn = browser.find_element_by_id("qr_submit_id") confirmBtn.click() break #依次查找trains中的車次是否有票,有的話點擊購買
所以,如果你有特別心儀的車次,可以在trains中放在最前面,依次填寫覺得還行的車次。至此,應用python解鎖搶票軟件背后的原理已講解完畢,感興趣的朋友可以自己跟著本文實現(xiàn)一遍。
12306不定期會更新買票界面,所以過一段時間可能之前的代碼就要進行一些調(diào)整,需要自己弄清里面的原理,才可以以不變應萬變。本文的代碼沒有進行高級的封裝,只為大家能更清楚地了解每一步,能在搶票高峰期買到自己心儀的票。
也寫得很基礎,沒有進一步的調(diào)優(yōu)縮短時效,感興趣的朋友可以自行研究,如有任何疑問可以跟我溝通。?
到此這篇關于Python實現(xiàn)12306自動搶火車票功能的文章就介紹到這了,更多相關Python自動搶火車票內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Keras構(gòu)建神經(jīng)網(wǎng)絡踩坑(解決model.predict預測值全為0.0的問題)
這篇文章主要介紹了Keras構(gòu)建神經(jīng)網(wǎng)絡踩坑(解決model.predict預測值全為0.0的問題),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07python實現(xiàn)文件批量編碼轉(zhuǎn)換及注意事項
本文通過實例代碼給大家介紹了python實現(xiàn)文件批量編碼轉(zhuǎn)換及注意事項,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2019-10-10python3線程池ThreadPoolExecutor處理csv文件數(shù)據(jù)
這篇文章主要為大家介紹了python3線程池ThreadPoolExecutor處理csv文件數(shù)據(jù)實現(xiàn)的實例過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06python 去除txt文本中的空格、數(shù)字、特定字母等方法
今天小編就為大家分享一篇python 去除txt文本中的空格、數(shù)字、特定字母等方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07