欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

春節(jié)到了 教你使用python來搶票回家

 更新時(shí)間:2020年01月06日 09:08:32   作者:編程入門到放棄  
這篇文章主要介紹了春節(jié)到了 教你使用python來搶票回家,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了春節(jié)到了 教你使用python來搶票回家,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

不知不覺,一年一度的春運(yùn)搶票大幕已經(jīng)拉開,想快速搶到回家的車票嗎?作為程序員,這些技術(shù)手段,你一定要知道。

為了讓大家更快捷更便利的搶火車票,各種各樣的搶票軟件應(yīng)需而生,這類軟件大部分都是付費(fèi)搶票的機(jī)制。

作為程序員,如何用技術(shù)手段搶到回家的票?來看看用 Python 寫的搶票腳本。

手把手教你用 Python 搶票回家過年

環(huán)境介紹

  • windows 8.1
  • python3.6.1
  • firefox插件 geckodriver.exe

操作步驟

引入要的模塊

from selenium import webdriver   #控制瀏覽器
    from selenium.webdriver.common.keys import Keys #用于給元素賦值
    import time  #時(shí)間模塊
    from selenium.webdriver.support.select import Select #控制下拉框模塊
    from selenium.webdriver.common.by import By  #尋找元素模塊
    from selenium.webdriver.support.ui import WebDriverWait #“顯示等待”模塊
    from selenium.webdriver.support import expected_conditions as EC #等待條件模塊

登陸模塊

首先需要選擇使用的瀏覽器,此處以 firefox 為例,下載:geckodriver.exe 。

提到的 stations.txt 可以直接看這個(gè):

車站信息:

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

將 geckodriver.exe 放到 python.exe 同級(jí)目錄下即可(如果有報(bào)錯(cuò)的情況下,放一個(gè)該文件到與 firefox.exe 同級(jí)目錄下,并添加環(huán)境變量)

#可以用input,也可以直接放入到后面的用戶名、密碼輸入框中
    #可以利用標(biāo)準(zhǔn)輸入進(jìn)行批量的操作,此處以個(gè)人搶票操作為例
    # username = str(input('請(qǐng)輸入你的用戶名:'))
    # password = str(input('請(qǐng)輸入你的密碼:')) #這兩行可以暫時(shí)忽略

    browser = webdriver.Firefox()   #驅(qū)動(dòng)firefox瀏覽器
    browser.get("https://kyfw.12306.cn/otn/login/init")  #啟動(dòng)瀏覽器后進(jìn)入該鏈接下
    browser.find_element_by_id('username').clear()
    browser.find_element_by_id('username').send_keys(‘xxxxx')  #xxxxx更換為用戶名 
    browser.find_element_by_id('password').send_keys(‘xxxxx')  #xxxxx更換為密碼  
    time.sleep(10)  #此時(shí)驗(yàn)證碼自行點(diǎn)擊,該處設(shè)置10秒延遲,可以自己設(shè)置
    try:
        browser.find_element_by_id('loginSub').click()   #點(diǎn)擊登陸操作,該id為登陸按鈕
        #或者 browser.find_element_by_link_text('登陸').click() #標(biāo)簽顯示的名稱
    except:
        browser.find_element_by_class_name('touclick-bgimg touclick-reload touclick-reload-normal').click()   #try中驗(yàn)證碼輸入點(diǎn)錯(cuò)了會(huì)在此處刷新一次
        time.sleep(20)           #第二次輸入驗(yàn)證碼前等待20秒,可以自己設(shè)置,第一次輸入無誤直接跳過
        browser.find_element_by_id('loginSub').click()  #重新輸入驗(yàn)證碼后的點(diǎn)擊登陸

跳轉(zhuǎn)模塊

#默認(rèn)跳轉(zhuǎn)到首頁
    time.sleep(2)  #此處一般無需設(shè)置時(shí)間等待,調(diào)試代碼時(shí)使用
    clickReserve = browser.find_element_by_link_text('車票預(yù)訂').click() #跳轉(zhuǎn)到車票預(yù)定頁面,該頁面可以查詢票
    time.sleep(2)    #出發(fā)地點(diǎn)和到達(dá)地點(diǎn)設(shè)置
    #此處value值為出發(fā)時(shí)刻的地點(diǎn),BJP表示北京,更改value值在頁面上不加載,基本不耗時(shí)間,從頁面中也看不到出發(fā)地和目的地
    #此處內(nèi)容以爬取,保存在stations.txt中,每行表示一個(gè)地址,打開文檔ctrl + F查找即可
    jsf = 'var a = document.getElementById("fromStation");a.value = "BJP"'  #此處將BJP更換為你需要的出發(fā)地址,value值在以爬取到stations.txt中,自行查看
    browser.execute_script(jsf)
    jst = 'var a = document.getElementById("toStation");a.value = "LZJ"'  #終點(diǎn),同上方法
    browser.execute_script(jst)
    js = "document.getElementById('train_date').removeAttribute('readonly')"  #時(shí)間選擇時(shí)默認(rèn)為只讀,通過JS移除只讀屬性
    browser.execute_script(js)  #執(zhí)行JS語句
    browser.find_element_by_id('train_date').clear()  #時(shí)間元素中默認(rèn)有提示字,需要先清空
    browser.find_element_by_id('train_date').send_keys('2018-02-01')  #按照改格式輸入需要查詢的時(shí)間
    search = browser.find_element_by_id('query_ticket').click()  #輸入好信息時(shí)點(diǎn)擊查詢,該處存在成人票和學(xué)生票,默認(rèn)是成人票,如果購買,對(duì)學(xué)生票處執(zhí)行以下語句即可:
    #browser.find_element_by_id('xxxx').click()  #對(duì)于id還是class或其它自行選擇

開始購票

此處,就是點(diǎn)擊預(yù)定的操作,我在這里只是舉一個(gè)方法例子,也可以通過不斷點(diǎn)擊直到成功(這樣可以避免網(wǎng)站倒計(jì)時(shí)和實(shí)際時(shí)間的時(shí)間差影響,但是不知道 12306 在搶票時(shí)對(duì)不斷快速訪問有沒有限制)。

start_time = "Thu Jan 04 08:00:00 2018"  #首先設(shè)置需要搶票的時(shí)間
    b = time.mktime(time.strptime(start_time,"%a %b %d %H:%M:%S %Y"))    print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime(b)) ) #此處是為了調(diào)試代碼使用,可忽略,不影響使用
    a = float(b)-time.time()  #利用自己設(shè)置的時(shí)間減去當(dāng)前時(shí)間的時(shí)間戳
    time.sleep(a)  #上一步驟得出的秒數(shù)就是需要等待搶票的時(shí)間
try:   #此處本來有try中的部分就夠了,WebDriverWait已有相應(yīng)等待重復(fù)訪問機(jī)制,默認(rèn)為0.5秒試驗(yàn)一次,except中添加是為了以防萬一
  WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "ticket_2400000Z550L")))  #查找需要預(yù)定的車次的id,直到出現(xiàn),10表示共等待10秒
  ticket = browser.find_element_by_xpath('//tr[@id="ticket_2400000Z550L"]/td[13]/a').click()  #點(diǎn)擊預(yù)定按鈕except:
  browser.find_element_by_id('query_ticket').click()
  WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "ticket_2400000Z550L")))
  ticket = browser.find_element_by_xpath('//tr[@id="ticket_2400000Z550L"]/td[13]/a').click()
"""
normalPassenger_8 數(shù)字表示該賬號(hào)下的第幾位,默認(rèn)從0開始如果是第一個(gè)則為normalPassenger_0
"""WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "normalPassenger_8")))
browser.find_element_by_id('normalPassenger_8').click()  #id中的8表示賬號(hào)下第九位s = Select(browser.find_element_by_id('seatType_1'))
s.select_by_value('6')  #此處value值看下方各個(gè)種類,6表示高級(jí)軟臥browser.find_element_by_id('submitOrder_id').click()
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "qr_submit_id")))
browser.find_element_by_link_text('提交訂單')
browser.find_element_by_id('qr_submit_id').click()#-------------------------------------------------結(jié)束#硬座 1#硬臥 3#軟臥 4#高級(jí)軟臥 6#二等座 O(大寫字母)#一等座 M#商務(wù)座 9

總結(jié)

需要替換的地方:

用戶名,密碼。

起始地點(diǎn)和目的地的 value 值,查 stations.txt 修改即可。

出發(fā)時(shí)間。

自己選擇車次的 xpath 路徑,路徑不用變,變對(duì)應(yīng) id 即可。

勾選用戶的位置(如果只要一個(gè)用戶,默認(rèn)用:normalPassenger_0)。

所選座位類別,默認(rèn)為有票的類別里最便宜的種類。

其余的在測(cè)試中都相同,沒有發(fā)現(xiàn)有變化,在使用前,可以測(cè)試一下代碼,測(cè)試是注意注釋掉提交訂單的代碼(下單有取消限制,每天好像只能取消三次),測(cè)試時(shí)網(wǎng)速正常。

有人說用瀏覽器執(zhí)行速度會(huì)慢,確實(shí)對(duì)于可以直接識(shí)別驗(yàn)證碼的腳本而言,沒有界面的會(huì)更快一些,但是實(shí)際上所用時(shí)間為預(yù)定開始到結(jié)束,相同網(wǎng)絡(luò)下,代碼執(zhí)行時(shí)間是要快于人工操作的,

另外,時(shí)間可以研究一下,之前研究過某寶的時(shí)間,秒殺時(shí)間是要比北京時(shí)間提前一點(diǎn)幾秒的,感覺全國各地有微小時(shí)間差的。

完整腳本示例

#python3.6.1#data:2018-01-03#author:LGC247CG"""
說明:
1.該腳本主要是提供一個(gè)實(shí)現(xiàn)思路,實(shí)現(xiàn)方法有很多,可以優(yōu)化的地方也有很多,觸發(fā)機(jī)制也可以自己設(shè)置,代碼以壓縮到最短,只是為了讓大家都可以看明白
2.正常網(wǎng)絡(luò)狀況下,不設(shè)置指定時(shí)間時(shí),從點(diǎn)擊確認(rèn)驗(yàn)證碼到下單基本上1秒左右,所以速度上還是沒問題的
3.由于同時(shí)勾選多人和單人使用所需時(shí)間基本相同,希望該方法只用于技術(shù)交流,請(qǐng)勿作為黃牛使用
4.在作為技術(shù)交流的情況下,如果驗(yàn)證碼可以實(shí)現(xiàn)將可以完全實(shí)現(xiàn)自動(dòng)搶票:
--1>驗(yàn)證碼有一定規(guī)律和數(shù)量,可以利用腳本獲取所有圖片,并加上相應(yīng)標(biāo)簽
--2>將頁面的文字和標(biāo)簽相匹配,再將圖片進(jìn)行相似度計(jì)算,對(duì)對(duì)應(yīng)圖片進(jìn)行點(diǎn)擊操作
--3>或是訓(xùn)練深度學(xué)習(xí)的圖片識(shí)別模型,通過算法識(shí)別
"""from selenium import webdriverfrom selenium.webdriver.common.keys import Keysimport timefrom selenium.webdriver.support.select import Selectfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Firefox()
browser.get("https://kyfw.12306.cn/otn/login/init")
browser.find_element_by_id('username').clear()
browser.find_element_by_id('username').send_keys('xxxxxxx')
browser.find_element_by_id('password').send_keys('xxxxxxx')
time.sleep(10)try:
  browser.find_element_by_id('loginSub').click()except:
  browser.find_element_by_class_name('touclick-bgimg touclick-reload touclick-reload-normal').click()
  time.sleep(15)
  browser.find_element_by_id('loginSub').click()#跳轉(zhuǎn)到車票預(yù)定頁面time.sleep(2)
clickReserve = browser.find_element_by_link_text('車票預(yù)訂').click()#出發(fā)地點(diǎn)和到達(dá)地點(diǎn)設(shè)置WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "fromStation")))
jsf = 'var a = document.getElementById("fromStation");a.value = "BJP"'browser.execute_script(jsf)
jst = 'var a = document.getElementById("toStation");a.value = "LZJ"'browser.execute_script(jst)
js = "document.getElementById('train_date').removeAttribute('readonly')"browser.execute_script(js)
browser.find_element_by_id('train_date').clear()
browser.find_element_by_id('train_date').send_keys('2018-02-02')
search = browser.find_element_by_id('query_ticket').click()#對(duì)于時(shí)間,我一直覺得網(wǎng)站計(jì)算的時(shí)間和自己獲取的時(shí)間差一秒左右,這個(gè)根據(jù)不同環(huán)境自己測(cè)試start_time = "Thu Jan 04 10:00:00 2018"  #首先設(shè)置需要搶票的時(shí)間b = time.mktime(time.strptime(start_time,"%a %b %d %H:%M:%S %Y"))
print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime(b)) ) #此處是為了調(diào)試代碼使用,可忽略,不影響使用a = float(b)-time.time()  #利用自己設(shè)置的時(shí)間減去當(dāng)前時(shí)間的時(shí)間戳time.sleep(a)  #上一步驟得出的秒數(shù)就是需要等待搶票的時(shí)間browser.find_element_by_id('query_ticket').click()  #時(shí)間到了先點(diǎn)擊查詢刷新一下,以防找不到元素try:
  WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "ticket_2400000Z550L")))
  ticket = browser.find_element_by_xpath('//tr[@id="ticket_2400000Z550L"]/td[13]/a').click()except:
  browser.find_element_by_id('query_ticket').click()
  WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "ticket_250000K8880L")))
  ticket = browser.find_element_by_xpath('//tr[@id="ticket_250000K8880L"]/td[13]/a').click()"""
normalPassenger_8 數(shù)字表示該賬號(hào)下的第幾位,默認(rèn)從0開始如果是第一個(gè)則為normalPassenger_0
"""WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "normalPassenger_8")))
browser.find_element_by_id('normalPassenger_8').click()
s = Select(browser.find_element_by_id('seatType_1'))
s.select_by_value('6')
browser.find_element_by_id('submitOrder_id').click()
WebDriverWait(browser,10).until(EC.presence_of_element_located((By.ID, "qr_submit_id")))
browser.find_element_by_link_text('提交訂單')#browser.find_element_by_id('qr_submit_id').click()

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python 使用socket傳輸圖片視頻等文件的實(shí)現(xiàn)方式

    python 使用socket傳輸圖片視頻等文件的實(shí)現(xiàn)方式

    這篇文章主要介紹了python 使用socket傳輸圖片視頻等文件的實(shí)現(xiàn)方式,本文給出了實(shí)例代碼,需要的朋友可以參考下
    2019-08-08
  • Python使用海龜繪圖實(shí)現(xiàn)貪吃蛇游戲

    Python使用海龜繪圖實(shí)現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了Python使用海龜繪圖實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Python將多個(gè)excel文件合并為一個(gè)文件

    Python將多個(gè)excel文件合并為一個(gè)文件

    這篇文章主要為大家詳細(xì)介紹了Python將多個(gè)excel文件合并為一個(gè)文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • tensorflow 獲取模型所有參數(shù)總和數(shù)量的方法

    tensorflow 獲取模型所有參數(shù)總和數(shù)量的方法

    今天小編就為大家分享一篇tensorflow 獲取模型所有參數(shù)總和數(shù)量的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • pandas聚合分組的具體使用

    pandas聚合分組的具體使用

    使用數(shù)據(jù)庫時(shí),我們利用查詢操作對(duì)各列或各行中的數(shù)據(jù)進(jìn)行分組,可以針對(duì)其中的每一組數(shù)據(jù)進(jìn)行各種不同的操作,本文主要介紹了pandas聚合分組,感興趣的可以了解一下
    2024-03-03
  • python神經(jīng)網(wǎng)絡(luò)使用tensorflow構(gòu)建長短時(shí)記憶LSTM

    python神經(jīng)網(wǎng)絡(luò)使用tensorflow構(gòu)建長短時(shí)記憶LSTM

    這篇文章主要為大家介紹了python機(jī)器學(xué)習(xí)tensorflow構(gòu)建長短時(shí)記憶網(wǎng)絡(luò)LSTM,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • python正則表達(dá)式的懶惰匹配和貪婪匹配說明

    python正則表達(dá)式的懶惰匹配和貪婪匹配說明

    這篇文章主要介紹了python正則表達(dá)式的懶惰匹配和貪婪匹配說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 基于python tornado實(shí)現(xiàn)圖床功能

    基于python tornado實(shí)現(xiàn)圖床功能

    因?yàn)橘I了阿里/騰訊的云服務(wù)器,但是使用云存儲(chǔ)還需要收費(fèi),又加上家里正好有一臺(tái)nas,又加上閑的沒事,所以搞了一個(gè)小腳本,這個(gè)項(xiàng)目主要功能是為typora增加一個(gè)自定義圖床,本文給大家介紹基于python tornado實(shí)現(xiàn)圖床功能,感興趣的朋友一起看看吧
    2023-08-08
  • Python3中詳解fabfile的編寫

    Python3中詳解fabfile的編寫

    這篇文章給大家分享了Python3中詳解fabfile的編寫的相關(guān)知識(shí)點(diǎn)以及重要內(nèi)容,有興趣的朋友跟著學(xué)習(xí)下。
    2018-06-06
  • Python引用計(jì)數(shù)操作示例

    Python引用計(jì)數(shù)操作示例

    這篇文章主要介紹了Python引用計(jì)數(shù)操作,結(jié)合實(shí)例形式分析了Python引用計(jì)數(shù)相關(guān)操作與運(yùn)行機(jī)制,需要的朋友可以參考下
    2018-08-08

最新評(píng)論