国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【selenium12306搶票購票腳本】肝了一周,2萬3千字超詳細(xì)代碼詳解 【建議收藏】

這篇具有很好參考價值的文章主要介紹了【selenium12306搶票購票腳本】肝了一周,2萬3千字超詳細(xì)代碼詳解 【建議收藏】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

? ? ? ? 大家好,我是好學(xué)的小師弟,由于沒搶到中秋回家的票,所以我寫了這個腳本,還有些模塊沒有完善,后期會補(bǔ)上。寫這個主要是用來加強(qiáng)自己對selenium和python的學(xué)習(xí)理解。該腳本僅供大家學(xué)習(xí)參考,輔助大家理解selenium知識。

目錄

一、鐵路12306登錄

1.反爬蟲

2.滑塊驗(yàn)證碼問題解決

3.登錄模塊完整代碼

二、出發(fā)地,目的地,乘車日期的選擇

1.乘車日期、出發(fā)地、目的地代碼思路和遇到的問題

2.乘車日期、出發(fā)地、目的地模塊代碼

三、購票、搶票模塊

1.流程概述

2.目前程序存在的缺點(diǎn)

3.程序難點(diǎn)(對我個人而言)?

4.搶票、購票模塊代碼

四、選座模塊

五、其他

1.查詢余票頁面,顯示頁面超時

2.pycharm與界面的切換

六、完整代碼


2021.9.24? 更新

一、鐵路12306登錄

首先我們打開12306的頁面,中國鐵路12306。發(fā)現(xiàn)頁面是需要二維碼登陸的,所以我們要在代碼里,先去選擇點(diǎn)擊賬號密碼登錄。

? ? ? ? ? ? ?12306搶票腳本,python,爬蟲,selenium,測試工具,chrome

1.反爬蟲

這里如果你直接輸入賬號密碼,是不會顯示出驗(yàn)證碼來的,直接給你報錯。輸入以下代碼即可解決問題

script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
driver.execute_script(script)

在代碼里輸入賬號和密碼后,會出現(xiàn)驗(yàn)證碼。這里的驗(yàn)證碼是滑塊驗(yàn)證碼,所以我們可以通過selenium的鼠標(biāo)事件來執(zhí)行。

from selenium.webdriver import ActionChains  #導(dǎo)入鼠標(biāo)事件

2.滑塊驗(yàn)證碼問題解決

思路:?先確定滑塊的初始位置元素,選中它,然后模擬鼠標(biāo)按住不放,向右平移拖動一定的距離,即可完成驗(yàn)證。驗(yàn)證后,釋放鼠標(biāo),不然后面鼠標(biāo)就用不了了(一直會處在這個命令執(zhí)行狀態(tài)中)。記得perform()執(zhí)行,這個指令不能忘

代碼:? ? ? ?? ? ??

#滑動驗(yàn)證碼
#定位驗(yàn)證碼的頭位置元素
time.sleep(1)
picture_start=driver.find_element_by_id('nc_1_n1z')
#移動到相應(yīng)的位置,并左鍵鼠標(biāo)按住往右邊拖
ActionChains(driver).move_to_element(picture_start).click_and_hold(picture_start).move_by_offset(300,0).release().perform()

效果圖:

? ? ? ? ? ? ? ? ? ??12306搶票腳本,python,爬蟲,selenium,測試工具,chrome?

3.登錄模塊完整代碼

from selenium import webdriver
import time
from selenium.webdriver import ActionChains  #導(dǎo)入鼠標(biāo)事件
from selenium.webdriver.common.keys import Keys    #鍵盤功能鍵封裝的一個函數(shù)
driver=webdriver.Chrome()  #驅(qū)動
url='https://kyfw.12306.cn/otn/resources/login.html'   #鐵路12306網(wǎng)址
driver.get(url)
#反爬蟲
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
driver.execute_script(script)
#窗口最小化
driver.minimize_window()
driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[2]/a').click()#點(diǎn)擊賬號密碼登錄
x=input('---輸入你的用戶名---\n')
driver.find_element_by_id('J-userName').send_keys(x)
y=input('---輸入你的密碼---\n')
driver.find_element_by_id('J-password').send_keys(y)
time.sleep(0.5)
driver.find_element_by_id('J-login').click()
#窗口最大化
driver.maximize_window()
#滑動驗(yàn)證碼
#定位驗(yàn)證碼的頭位置元素
time.sleep(1)
picture_start=driver.find_element_by_id('nc_1_n1z')
#移動到相應(yīng)的位置,并左鍵鼠標(biāo)按住往右邊拖
ActionChains(driver).move_to_element(picture_start).click_and_hold(picture_start).move_by_offset(300,0).release().perform()
#驗(yàn)證成功后,頁面會出現(xiàn)一個窗口 把他叉掉或者確定掉
time.sleep(3)
try:
    driver.find_element_by_class_name("modal-close").click()
    time.sleep(1)
except:
    print('---程序正在運(yùn)行---')
driver.find_element_by_xpath('//*[@id="J-index"]/a').click()
#最小化窗口
driver.minimize_window()
time.sleep(1)

二、出發(fā)地,目的地,乘車日期的選擇

1.乘車日期、出發(fā)地、目的地代碼思路和遇到的問題

登陸成功后,我們就來到了出發(fā)地,目的地和乘車日期的選擇界面。這里我們用到了selenium的封裝keys函數(shù),keys函數(shù)可以用來調(diào)用鍵盤上的一些功能鍵,比如control,enter,backspace等。通過keys函數(shù)我們就可以做到把輸入文本框里的內(nèi)容,全選+刪除,然后輸入我們想要的出發(fā)日期,目的地,出發(fā)地。

12306搶票腳本,python,爬蟲,selenium,測試工具,chrome

?注意:這里的出發(fā)日期是含有下拉框的,你輸入你想要的日期之后,下拉框還是不會消失,下拉框不消失,他就會覆蓋到你的查詢按鈕,從而導(dǎo)致你click不到查詢這個元素,無法完成接下來的操作,程序會報錯。這個時候你點(diǎn)擊空白處,下拉框才會消失,但是selenium中我沒定位到空白區(qū)域的元素(或者就是壓根沒有?懷疑中),所以我找了另一個方法,點(diǎn)擊靜態(tài)圖片,因?yàn)樗麄儧]有超鏈接,也就相當(dāng)于空白區(qū)域,從而達(dá)到使得下拉框消失的目的,讓程序可以接著運(yùn)行。

12306搶票腳本,python,爬蟲,selenium,測試工具,chrome

2.乘車日期、出發(fā)地、目的地模塊代碼

here_place=input('---你的出發(fā)地---\n')
driver.find_element_by_xpath('//*[@id="fromStationText"]').clear()
driver.find_element_by_xpath('//*[@id="fromStationText"]').send_keys(here_place)
time.sleep(0.5)
driver.find_element_by_xpath('//*[@id="fromStationText"]').send_keys(Keys.ENTER)
there_place=input('---你的目的地---\n')
driver.find_element_by_xpath('//*[@id="toStationText"]').clear()
driver.find_element_by_xpath('//*[@id="toStationText"]').send_keys(there_place)
driver.find_element_by_xpath('//*[@id="toStationText"]').send_keys(Keys.ENTER)
#買哪天的票,出發(fā)日期填寫
travel_date=input('由于疫情目前12306只支持提前15天買票\n出發(fā)日期格式:20xx-05-07\n')
#頁面最大化
#driver.maximize_window()
time.sleep(1)
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(Keys.CONTROL,'a')    #control+a全選
time.sleep(1)
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(Keys.BACKSPACE)
time.sleep(1)
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(travel_date)
driver.find_element_by_xpath('//*[@id="train_date"]').click()
time.sleep(1)
print('等待中')
time.sleep(0.5)

try:
    #不能一次性點(diǎn)到鏈接,那就中間再點(diǎn)兩次無用的靜態(tài)文字
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[4]/div[3]/div[1]/h3').click()
    time.sleep(2)
    driver.find_element_by_xpath('//*[@id="index_ads"]').click()
    time.sleep(2)
    # 點(diǎn)擊頁面上的靜態(tài)圖片(沒有內(nèi)含超鏈接),為了把上面車票的日期下拉框給去掉
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[5]/div[1]/div/h2').click()
except:
    driver.find_element_by_xpath('//*[@id="index_ads"]').click()
    time.sleep(2)
    #點(diǎn)擊頁面上的靜態(tài)圖片(沒有內(nèi)含超鏈接),為了把上面車票的日期下拉框給去掉
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[5]/div[1]/div/h2').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="search_one"]').click()
#叉掉疫情提示
time.sleep(2)

三、購票、搶票模塊

1.流程概述

12306每次都是在固定時間出售票的,一般是早上8點(diǎn)或者下午5點(diǎn)(時間有可能有變化,看情況)。所以,我們只需要在程序中加一個定時模塊就OK了,提前3分鐘執(zhí)行程序,就完成了搶票功能。

來說說購票

思路:點(diǎn)擊查詢按鈕,先詢問購票人是否需要購買學(xué)生票,然后輸入你想要乘坐的車次,這里我預(yù)選的是二等座,如果你想要乘坐硬座,列表[]里寫入15,我記得好象是,你可以把返回的字符串列表,打印出來,然后一個個數(shù),看硬座所對應(yīng)的位置是列表[]多少,然后改一下就行了。

查詢余票會出現(xiàn)兩種情況:

1.如果有余票,直接幫你預(yù)定,程序跳到下一步選座模塊。

2.沒有余票了或者票還沒發(fā)售,程序開始不停的點(diǎn)擊查詢按鈕,一旦發(fā)售或者有票,立刻幫你預(yù)定上(這里我好像只設(shè)置了運(yùn)行30秒,我覺得30秒沒搶到票,基本也沒戲了。。。>-<)搶到票,就跳到選座模塊;搶不到,瀏覽器直接退出。

2.目前程序存在的缺點(diǎn)

如果12306的頁面搜索出現(xiàn)兩行同名稱的列車車次,并且你想乘坐這輛車,他只會選中第一輛車

12306搶票腳本,python,爬蟲,selenium,測試工具,chrome
目前只支持購買一個人的票,并且是乘車人列表出現(xiàn)的第一個人

3.程序難點(diǎn)(對我個人而言)?

1.xpath的元素定位

/? 絕對定位??

//相對定位

.? 當(dāng)前節(jié)點(diǎn)

.//a[@id='蘇州']? ?當(dāng)前節(jié)點(diǎn)的相對位置下 a標(biāo)簽中的屬性為id的,且id的值為蘇州的xpath路徑

通過這種純手寫的xpath路徑方法,可以更快的獲得我們想要的元素

如果我們f12,點(diǎn)擊元素,右鍵copy中選擇xpath,往往得到的是含有通配符的//*[@id='蘇州'],這種方法,往往只能獲取到一個元素,但我們想要爬的是一個列表,所以這種方法在這個時候,就不是那么合適。

2.字符串如何變成列表?

我們爬下來的所乘日期當(dāng)天的班次是字符串,所以我們需要把字符串變?yōu)榱斜?。不然的話,不好定位,不好寫輸出哪個值

兩種方法

第一種? 分-總形式

自己定義一個空列表,然后for in 遍歷;空列表進(jìn)行追加,把車次,二等座,硬座,余票等等這些全部挨個建列表,然后再通過一個for in遍歷找到你所想要的那個車次,看循環(huán)第幾遍找到,然后列表輸出那個數(shù)字-1,這樣子就找到了,我們想要的信息了

第二種方法? 總—split函數(shù)—>字符串列表

直接把當(dāng)天的班次,全部打印出來,找共同點(diǎn),通過split函數(shù)對他們進(jìn)行切片,分割。split返回的即是字符串列表。這個更方便一點(diǎn)

3.邏輯思考

這里就是if else? ?try except? 這些邏輯上的編寫, 還有break的循環(huán)跳出 ,還有就是自定義函數(shù)的編寫調(diào)用。這點(diǎn)就是要考慮的場景太多了,耗時間和邏輯太多。。。所以我直接把場景設(shè)置死了,但是還是會有很多可能性。。。

4.搶票、購票模塊代碼


#看乘車人是否為學(xué)生,是否想購買學(xué)生票
def student():
    stu=input('是否購買學(xué)生票,請輸入是或否\n')
    if stu=='否':
        driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
        accept_stu='已選擇成人票'
    else:
        stu_element=driver.find_element_by_xpath('//*[@id="sf2"]')
        stu_element.click()
        time.sleep(1)
        driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
        accept_stu='已勾選購買學(xué)生票'
    return accept_stu

student()
time.sleep(1)


#還沒開始售票,在不斷點(diǎn)擊預(yù)定按鈕

def refresh_search_ticket(train_message,train_number):
    for times in range(0,31):
        success_message=''
        if times<30:
            driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
            time.sleep(1)
            if'有'==train_message[10]or'有'==train_message[9]:
                print('---您選的車次二等座有票了,正在為您預(yù)定---')
                time.sleep(0.5)
                button = train_number.find_element_by_xpath('.//a[@class="btn72"]')  # 已經(jīng)鎖定車次,對當(dāng)前車次進(jìn)行車票預(yù)定
                time.sleep(0.5)
                button.click()
                # .//a[@class="btn72"]意思就是取a標(biāo)簽的屬性為class的值為btn72的元素xpath
                time.sleep(1)
                success_message='---預(yù)定成功,現(xiàn)在正在選擇乘車人---'
                print('---預(yù)定成功,現(xiàn)在正在選擇乘車人---')
                break
            else:
                print('繼續(xù)點(diǎn)擊查詢按鈕,刷新余票',end='\r')

        else:
            time.sleep(1)
            success_message='---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---'
            time.sleep(0.5)
            print('---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---')
            break
    return success_message


def order_ticket():
    train_num=input('---輸入你想乘坐的火車車次---\n')
    train_numbers = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
    #記得在元素element后面加s,因?yàn)橛泻枚鄠€元素,這里定位的是不含datatran的所有元素
    for train_number in train_numbers:
        order_ticket_message=''
        train_messages=train_number.text.replace('\n',' ')#把換行符替換成空格
        train_message=train_messages.split(' ')
        '''
                split():拆分字符串。通過指定分隔符對字符串進(jìn)行切片,并返回分割后的字符串列表(list)
        '''
        if train_num==train_message[0]:
            print('---找到你想要的車次了---')
            if'有'==train_message[10]or'有'==train_message[9]:#這里的列表數(shù)值,各個車可能有出入,到時候大家打印下整個車次列表,然后再改下數(shù)字就行了
                print('---該車次現(xiàn)在有二等座---')
                time.sleep(1)
                button=train_number.find_element_by_xpath('.//a[@class="btn72"]')#已經(jīng)鎖定車次,對當(dāng)前車次進(jìn)行車票預(yù)定
                button.click()
                #.//a[@class="btn72"]意思就是取a標(biāo)簽的屬性為class的值為btn72的元素xpath
                time.sleep(1)
                order_ticket_message='預(yù)定成功,現(xiàn)在正在選擇乘車人'
                print('預(yù)定成功,現(xiàn)在正在選擇乘車人')
                break
            else:
                print('---抱歉,您所選的車次車票,目前沒票了,存在有候補(bǔ)票這種情況,正在為你刷新頁面,實(shí)時更新車票情況---')
                
                result='---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---'
                time.sleep(1)
                success_messages=refresh_search_ticket(train_message,train_number)
               
                if result==success_messages:
                    time.sleep(1)
                    order_ticket_message='---本次搶票已結(jié)束,祝你好運(yùn)---'
                    print('---本次搶票已結(jié)束,祝你好運(yùn)---')
                    break
                else:
                    order_ticket_message='查到票了,預(yù)定成功,開始選乘坐人'
                    print('查到票了,預(yù)定成功,開始選乘坐人')
                    break
        else:
            print('---正在查詢你所需要的車次---',end='\r')  #覆蓋前面一句---正在查詢你所需要的車次---,不然每循環(huán)一次,就會打印一次這句話

    return order_ticket_message

finally_message=order_ticket()


if finally_message=='---本次搶票已結(jié)束,祝你好運(yùn)---':
    print('---即將關(guān)閉瀏覽器打開的所有窗口---')
    driver.quit()
    time.sleep(1)
    print('---瀏覽器已關(guān)閉---')
else:
    
    time.sleep(2)
    # 點(diǎn)擊乘車人信息,默認(rèn)第一個為本人
    driver.find_element_by_xpath('//*[@id="normalPassenger_0"]').click()
    print('---乘車人選擇成功,默認(rèn)選擇12306上面乘車人列表的第一位---')
    time.sleep(0.5)
    點(diǎn)擊提交訂單
    driver.find_element_by_xpath('//*[@id="submitOrder_id"]').click()

四、選座模塊

因?yàn)?2306每天只有3次機(jī)會退票,好象是。所以我沒法多測試這個模塊到底行不行。。。。

#選座,報錯預(yù)警>_<  。。??赡軙婕暗骄W(wǎng)絡(luò)超時問題
print('---窗戶 A B C 過道 D F窗戶---')
time.sleep(1)
seat=input('---輸入你想要的位置,如果沒有該位置,隨機(jī)為你選擇一個位置---\n---輸入格式:place_X---\n---X為A B C D F---\n')
time.sleep(1)
seat_A='//*[@id="1A"]'  #座位
seat_B='//*[@id="1B"]'
seat_C='//*[@id="1C"]'
seat_D='//*[@id="1D"]'
seat_F='//*[@id="1F"]'
decision_true='//*[@id="qr_submit_id"]'  #確定按鈕
pay_money='---沒有自己想要選擇的位置了,隨機(jī)!---'



try:
    seat=='place_A'
    driver.find_element_by_xpath(seat_A).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_A'
except:
    driver.find_element_by_xpath(seat_A).click()
    time.sleep(1)
    print('你選的不是位置A/沒有位置A了')
    time.sleep(1)

try:
    seat == 'place_B'
    driver.find_element_by_xpath(seat_B).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_B'
except:

    time.sleep(1)
    print('你選的不是位置B/沒有位置B了')
    time.sleep(1)

try:
    seat=='place_C'
    driver.find_element_by_xpath(seat_C).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_C'
except:
    time.sleep(1)
    print('你選的不是位置C/沒有位置C了')
    time.sleep(1)

try:
    seat=='place_D'
    driver.find_element_by_xpath(seat_D).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_D'
except:
    time.sleep(1)
    print('你選的不是位置D/沒有位置D了')
    time.sleep(1)

try:
    seat=='place_F'
    driver.find_element_by_xpath(seat_F).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_F'
except:
    time.sleep(1)
    print('你選的不是位置F/沒有位置F了')
    time.sleep(1)


if pay_money !='---選座成功!寶貝,快來付錢---':
    print(pay_money)
    driver.find_element_by_xpath(decision_true).click()
    time.sleep(1)
    print('15分鐘內(nèi),快去掃碼付錢!')
else:
    print('15分鐘內(nèi),快去掃碼付錢!')

pay_result=input('---付款是否成功,選擇是或否---')
if pay_result=='是':
    driver.quit()
else:
    print('---selenium不穩(wěn)定---')

五、其他

1.查詢余票頁面,顯示頁面超時

晚上10點(diǎn)后,12306pc網(wǎng)頁就不太行了,一直顯示超時,所以我們就盡量不要在這個時候去登陸,我也寫了一個刷新函數(shù),有效果,雖然解決了這個頁面超時問題,但是選座的時候,還會出現(xiàn)新的網(wǎng)絡(luò)超時問題。。。。

2.pycharm與界面的切換

在pycharm下方出現(xiàn) '等待中' 以后的那個查詢余票界面,要切出來到pycharm中繼續(xù)寫你的需求,這個切換,最好用tab+alt。


六、完整代碼

from selenium import webdriver
import time
from selenium.webdriver import ActionChains  #導(dǎo)入鼠標(biāo)事件
from selenium.webdriver.common.keys import Keys    #鍵盤功能鍵封裝的一個函數(shù)

'''
by csdn 好學(xué)的小師弟
博客:https://blog.csdn.net/weixin_43784564
新人小白,歡迎大家一起學(xué)習(xí),交流,互相進(jìn)步

注:本文目前還差一個定時執(zhí)行任務(wù)腳本,且目前只支持選擇含有二等座選項(xiàng)的車次,購買的也是二等座。
   如果12306的頁面搜索出現(xiàn)兩行同名稱的列車車次,這個程序就會報錯
   目前只支持購買一個人的票
   目前只測出這些bug,還有好多種乘車情況沒考慮,因?yàn)檫壿嬏嗔?,寫不來了,白天要打? >_<
   
如果想要自動執(zhí)行,就把input寫死,然后加個定時執(zhí)行腳本就行了
注意:12306網(wǎng)頁晚上10點(diǎn)左右好像就不靈光了,打開有困難,一直顯示頁面超時
     頁面和pycharm之間切換,用tab+alt
     如果報錯,要么就是網(wǎng)絡(luò)問題、又要你重新登陸了,多試幾次
     要么就是selenium不穩(wěn)定。
     要么就是我寫的程序有問題,邏輯出錯??上覜]時間去測試改了
     (主要是選座的那一塊,我發(fā)博客之前零食寫的,沒時間了,tfs一堆任務(wù)要去忙)
     白天打工太累了。。。。。
     如果這個腳本對大家學(xué)習(xí)selenium和python有幫助的話,大家可以寫一個完善版
     如果程序一直報錯,那就把選座模塊注釋掉,再運(yùn)行;
     我昨晚試了下沒有選座模塊的程序,是能正常運(yùn)行的。
     選座模塊是我今天中午吃飯的時候?qū)懙模€沒來得及測試。


本腳本,僅用來讓大家互相交流學(xué)習(xí),大家一起共同進(jìn)步!

'''
driver=webdriver.Chrome()  #驅(qū)動
url='https://kyfw.12306.cn/otn/resources/login.html'   #鐵路12306網(wǎng)址
driver.get(url)
#反爬蟲
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
driver.execute_script(script)
#窗口最小化
driver.minimize_window()
driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[2]/a').click()#點(diǎn)擊賬號密碼登錄
x=input('---輸入你的用戶名---\n')
driver.find_element_by_id('J-userName').send_keys(x)
y=input('---輸入你的密碼---\n')
driver.find_element_by_id('J-password').send_keys(y)
time.sleep(0.5)
driver.find_element_by_id('J-login').click()
#窗口最大化
driver.maximize_window()
#滑動驗(yàn)證碼
#定位驗(yàn)證碼的頭位置元素
time.sleep(1)
picture_start=driver.find_element_by_id('nc_1_n1z')
#移動到相應(yīng)的位置,并左鍵鼠標(biāo)按住往右邊拖
ActionChains(driver).move_to_element(picture_start).click_and_hold(picture_start).move_by_offset(300,0).release().perform()
#有頁面有個窗口 把他叉掉或者確定掉
time.sleep(3)
try:
    driver.find_element_by_class_name("modal-close").click()
    time.sleep(1)
except:
    print('---程序正在運(yùn)行---')
driver.find_element_by_xpath('//*[@id="J-index"]/a').click()
#最小化窗口
driver.minimize_window()
time.sleep(1)
here_place=input('---你的出發(fā)地---\n')
driver.find_element_by_xpath('//*[@id="fromStationText"]').clear() #清除對話框原內(nèi)容,這里用的是clear函數(shù)
driver.find_element_by_xpath('//*[@id="fromStationText"]').send_keys(here_place)#輸入你的出發(fā)地
time.sleep(0.5)
#因?yàn)?2306輸入出發(fā)地存在一個下拉框問題,所以這里我們使用keys這個封裝好的函數(shù),來調(diào)用鍵盤上的回車鍵,這樣就避免了鼠標(biāo)點(diǎn)擊空白處 這個操作
driver.find_element_by_xpath('//*[@id="fromStationText"]').send_keys(Keys.ENTER)
there_place=input('---你的目的地---\n')
driver.find_element_by_xpath('//*[@id="toStationText"]').clear()
driver.find_element_by_xpath('//*[@id="toStationText"]').send_keys(there_place)
driver.find_element_by_xpath('//*[@id="toStationText"]').send_keys(Keys.ENTER)
#買哪天的票,出發(fā)日期填寫
travel_date=input('由于疫情目前12306只支持提前15天買票\n出發(fā)日期格式:20xx-05-07\n')
time.sleep(1)
#這里用的是keys函數(shù),調(diào)用ctrl+a全選,然后按刪除鍵,刪除原對話框內(nèi)容
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(Keys.CONTROL,'a')    #control+a全選
time.sleep(1)
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(Keys.BACKSPACE)
time.sleep(1)
driver.find_element_by_xpath('//*[@id="train_date"]').send_keys(travel_date)
driver.find_element_by_xpath('//*[@id="train_date"]').click()
time.sleep(1)
print('等待中')
time.sleep(0.5)

'''
這里注意,就算你輸入了訂票日期,下拉框也依舊存在,這里我們使用以下方法,解決這個問題,詳細(xì)解釋
https://blog.csdn.net/weixin_43784564/article/details/120352680
'''

try:
    #不能一次性到鏈接,那就中間再點(diǎn)兩次無用的靜態(tài)文字
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[4]/div[3]/div[1]/h3').click()
    time.sleep(2)
    driver.find_element_by_xpath('//*[@id="index_ads"]').click()
    time.sleep(2)
    # 點(diǎn)擊頁面上的靜態(tài)圖片(沒有內(nèi)含超鏈接),為了把上面車票的日期下拉框給去掉
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[5]/div[1]/div/h2').click()
except:
    driver.find_element_by_xpath('//*[@id="index_ads"]').click()
    time.sleep(2)
    #點(diǎn)擊頁面上的靜態(tài)圖片(沒有內(nèi)含超鏈接),為了把上面車票的日期下拉框給去掉
    driver.find_element_by_xpath('//*[@id="toolbar_Div"]/div[5]/div[1]/div/h2').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="search_one"]').click()
#叉掉疫情提示
time.sleep(2)

'''
為什么要獲得窗口句柄,詳細(xì)解釋詳見我上一條csdn博客https://blog.csdn.net/weixin_43784564/article/details/120368372
'''
# 獲取打開的多個窗口句柄
windows = driver.window_handles
# 切換到當(dāng)前最新打開的窗口
driver.switch_to.window(windows[-1])
time.sleep(2)

#窗口最大化
driver.maximize_window()
time.sleep(2)




#這里打開頁面會有一個溫馨提示,把他叉掉
try:
    driver.find_element_by_xpath('//*[@id="gb_closeDefaultWarningWindowDialog_id"]').click()
except:
    print('---這個溫馨提示我沒叉掉/不存在溫馨提示---')


#現(xiàn)在來到了購票頁面,點(diǎn)擊查詢按鈕
#這里出現(xiàn)一個問題,會出現(xiàn)頁面查詢超時,所以我們應(yīng)該搞個功能,即點(diǎn)擊按鈕,直到出現(xiàn)車次情況?。?!用到自己寫的一個函數(shù)

driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
time.sleep(2)
driver.minimize_window()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
time.sleep(2)

#如果頁面查詢超時,就用下面這個函數(shù)
def refresh_yemian():
    successful_search = ''
    try:
        time.sleep(1)
        driver.find_element_by_xpath('//*[@id="float"]/th[1]').click()
        time.sleep(1)
        successful_search='---查詢頁面正常,可正常查詢車次---'
        time.sleep(1)
    except:
        print('---正在點(diǎn)擊查詢按鈕---',end='\r')
        time.sleep(1)
        driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
        time.sleep(1)
        refresh_yemian()
    return successful_search

refresh_yemian()
time.sleep(1)

#看乘車人是否為學(xué)生,是否想購買學(xué)生票
def student():
    stu=input('是否購買學(xué)生票,請輸入是或否\n')
    if stu=='否':
        driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
        accept_stu='已選擇成人票'
    else:
        stu_element=driver.find_element_by_xpath('//*[@id="sf2"]')
        stu_element.click()
        time.sleep(1)
        driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
        accept_stu='已勾選購買學(xué)生票'
    return accept_stu

student()
time.sleep(1)

#注意,本搶票腳本只適用于開始售票的那幾分鐘有用,畢竟搶票就搶那幾分鐘
#注意,本搶票腳本還差一個定時執(zhí)行任務(wù)腳本。需要你定個時

#定義一個函數(shù),如果發(fā)現(xiàn)目前頁面沒票了,就不斷刷新頁面,給你查詢是否有票現(xiàn)在.
def refresh_search_ticket(train_message,train_number):
    for times in range(0,31):
        success_message=''
        if times<30:
            driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
            time.sleep(1)
            if'有'==train_message[10]or'有'==train_message[9]:
                print('---您選的車次二等座有票了,正在為您預(yù)定---')
                time.sleep(0.5)
                button = train_number.find_element_by_xpath('.//a[@class="btn72"]')  # 已經(jīng)鎖定車次,對當(dāng)前車次進(jìn)行車票預(yù)定
                time.sleep(0.5)
                button.click()
                # .//a[@class="btn72"]意思就是取a標(biāo)簽的屬性為class的值為btn72的元素xpath
                time.sleep(1)
                success_message='---預(yù)定成功,現(xiàn)在正在選擇乘車人---'
                print('---預(yù)定成功,現(xiàn)在正在選擇乘車人---')
                break
            else:
                print('繼續(xù)點(diǎn)擊查詢按鈕,刷新余票',end='\r')

        else:
            time.sleep(1)
            success_message='---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---'
            time.sleep(0.5)
            print('---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---')
            break
    return success_message


#輸入你想乘坐的車次,訂票
def order_ticket():
    train_num=input('---輸入你想乘坐的火車車次---\n')
    train_numbers = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
    #記得在元素element后面加s,因?yàn)橛泻枚鄠€元素,這里定位的是不含datatran的所有元素
    for train_number in train_numbers:
        order_ticket_message=''
        train_messages=train_number.text.replace('\n',' ')#把換行符替換成空格
        train_message=train_messages.split(' ') #split切割函數(shù),用' '來切片,并返回字符串列表

        if train_num==train_message[0]:
            print('---找到你想要的車次了---')
            if'有'==train_message[10]or'有'==train_message[9]:#這里的列表數(shù)值,各個車可能有出入,到時候大家打印下整個車次列表,然后再改下數(shù)字就行了,一般來說是不用改的
                print('---該車次現(xiàn)在有二等座---')
                time.sleep(1)
                button=train_number.find_element_by_xpath('.//a[@class="btn72"]')#已經(jīng)鎖定車次,對當(dāng)前車次進(jìn)行車票預(yù)定
                button.click()
                #.//a[@class="btn72"]意思就是取當(dāng)前節(jié)點(diǎn),相對路徑下的a標(biāo)簽的屬性為class的值為btn72的元素xpath
                time.sleep(1)
                order_ticket_message='預(yù)定成功,現(xiàn)在正在選擇乘車人'
                print('預(yù)定成功,現(xiàn)在正在選擇乘車人')
                break
            else:
                print('---抱歉,您所選的車次車票,目前沒票了,存在有候補(bǔ)票這種情況,正在為你刷新頁面,實(shí)時更新車票情況---')
                result='---查詢時間已到!抱歉,您所選的車次,目前沒有二等座的票了,您可去12306官網(wǎng),繼續(xù)查詢---'
                time.sleep(1)
                #沒票了,現(xiàn)在調(diào)用不斷刷新頁面的函數(shù),來給你查詢余票,并返回值
                success_messages=refresh_search_ticket(train_message,train_number)

                if result==success_messages:
                    time.sleep(1)
                    order_ticket_message='---本次搶票已結(jié)束,祝你好運(yùn)---'
                    print('---本次搶票已結(jié)束,祝你好運(yùn)---')
                    break
                else:
                    order_ticket_message='查到票了,預(yù)定成功,開始選乘坐人'
                    print('查到票了,預(yù)定成功,開始選乘坐人')
                    break
        else:
            print('---正在查詢你所需要的車次---',end='\r')  #覆蓋前面一句---正在查詢你所需要的車次---,不然每循環(huán)一次,就會打印一次這句話

    return order_ticket_message

finally_message=order_ticket()
if finally_message=='---本次搶票已結(jié)束,祝你好運(yùn)---':
    print('---即將關(guān)閉瀏覽器打開的所有窗口---')
    driver.quit()
    time.sleep(1)
    print('---瀏覽器已關(guān)閉---')
else:
    time.sleep(2)
    # 點(diǎn)擊乘車人信息,默認(rèn)第一個為本人
    driver.find_element_by_xpath('//*[@id="normalPassenger_0"]').click()
    time.sleep(1)
    print('---乘車人選擇成功,默認(rèn)選擇12306上面乘車人列表的第一位---')
    time.sleep(1)
    #點(diǎn)擊提交訂單
    driver.find_element_by_xpath('//*[@id="submitOrder_id"]').click()
    time.sleep(1)
    print('---已提交訂單---')
    time.sleep(1)
    
    
    #下面可能存在邏輯錯誤
#選座
print('---窗戶 A B C 過道 D F窗戶---')
time.sleep(1)
seat=input('---輸入你想要的位置,如果沒有該位置,隨機(jī)為你選擇一個位置---\n---輸入格式:place_X---\n---X為A B C D F---\n')
time.sleep(1)
seat_A='//*[@id="1A"]'  #座位
seat_B='//*[@id="1B"]'
seat_C='//*[@id="1C"]'
seat_D='//*[@id="1D"]'
seat_F='//*[@id="1F"]'
decision_true='//*[@id="qr_submit_id"]'  #確定
pay_money='---沒有自己想要選擇的位置了,隨機(jī)!---'



try:
    seat=='place_A'
    driver.find_element_by_xpath(seat_A).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_A'
except:
    driver.find_element_by_xpath(seat_A).click()
    time.sleep(1)
    print('你選的不是位置A/沒有位置A了')
    time.sleep(1)

try:
    seat == 'place_B'
    driver.find_element_by_xpath(seat_B).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_B'
except:

    time.sleep(1)
    print('你選的不是位置B/沒有位置B了')
    time.sleep(1)

try:
    seat=='place_C'
    driver.find_element_by_xpath(seat_C).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_C'
except:
    time.sleep(1)
    print('你選的不是位置C/沒有位置C了')
    time.sleep(1)

try:
    seat=='place_D'
    driver.find_element_by_xpath(seat_D).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_D'
except:
    time.sleep(1)
    print('你選的不是位置D/沒有位置D了')
    time.sleep(1)

try:
    seat=='place_F'
    driver.find_element_by_xpath(seat_F).click()
    time.sleep(1)
    driver.find_element_by_xpath(decision_true).click()
    pay_money = '---選座成功!寶貝,快來付錢---'
    print('---選座成功!寶貝,快來付錢---')
    time.sleep(1)
    seat = 'place_F'
except:
    time.sleep(1)
    print('你選的不是位置F/沒有位置F了')
    time.sleep(1)


if pay_money !='---選座成功!寶貝,快來付錢---':
    print(pay_money)
    driver.find_element_by_xpath(decision_true).click()
    time.sleep(1)
    print('15分鐘內(nèi),快去掃碼付錢!')
else:
    print('15分鐘內(nèi),快去掃碼付錢!')

pay_result=input('---付款是否成功,選擇是或否---')
if pay_result=='是':
    driver.quit()
else:
    print('---selenium不穩(wěn)定---')

新人創(chuàng)作不易,覺得不錯的看官,點(diǎn)個贊吧,么么噠!??!

該篇僅用來學(xué)習(xí),禁止轉(zhuǎn)載!文章來源地址http://www.zghlxwxcb.cn/news/detail-601952.html

到了這里,關(guān)于【selenium12306搶票購票腳本】肝了一周,2萬3千字超詳細(xì)代碼詳解 【建議收藏】的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 28. 實(shí)戰(zhàn):基于selenium實(shí)現(xiàn)12306自動購票

    28. 實(shí)戰(zhàn):基于selenium實(shí)現(xiàn)12306自動購票

    目錄 前言 目的 思路 代碼實(shí)現(xiàn) 1. 進(jìn)入登錄界面,輸入賬號密碼 2. 點(diǎn)擊登錄按鈕,完成滑塊驗(yàn)證 3. 在個人中心點(diǎn)擊購票,跳轉(zhuǎn) 4. 輸入出發(fā)地、目的地,從控制臺輸入得到 5. 文本框輸入出發(fā)日 6. 若是學(xué)生票則切換票型 7. 點(diǎn)擊查詢 8.?定位預(yù)定按鈕,點(diǎn)擊跳轉(zhuǎn)購票頁面 9.?選擇

    2024年01月22日
    瀏覽(21)
  • 基于selenium的大麥網(wǎng)自動搶票腳本

    基于selenium的大麥網(wǎng)自動搶票腳本

    先配置webdriver ? 記錄cookie,設(shè)置免密登錄? 購票頁面下單 ? 選擇座位+選擇場次,票檔(因?yàn)闄z索是否需要選擇座位要浪費(fèi)點(diǎn)時間,所以直接寫了兩個方法,看著選) ? 不用選擇座位,直接選擇給場次票檔和數(shù)量 提交訂單 ? 購票頁面點(diǎn)擊加票按鈕? 判斷XPATH是否存在 ? 頁

    2024年02月14日
    瀏覽(23)
  • 基于Python和Selenium的大麥網(wǎng)自動搶票腳本

    自動化搶票的腳本,需通過Selenium庫來實(shí)現(xiàn)自動化操作。(學(xué)習(xí)參考) 優(yōu)化后的完整代碼: 需要注意的: 我用了 with 語句保證瀏覽器實(shí)例在函數(shù)結(jié)束后正確關(guān)閉。 我用了幾個 try-except 塊處理在各個步驟可能出現(xiàn)的異常,它可以在異常的時候打印出錯誤的信息。 我把大部分代

    2024年02月11日
    瀏覽(27)
  • 爬蟲日常-12306自動購票程序

    爬蟲日常-12306自動購票程序

    hello兄弟們,最近在鉆研新鮮知識,一不留神沒想起來更新。今天我們順著前面幾篇文章完整的寫出一篇12306的自動購票軟件。 首先把我們已經(jīng)寫完的前期步驟代碼再順一遍 在前面幾篇文章中,我們實(shí)現(xiàn)了自動打開瀏覽器并且完成登錄以及繞過驗(yàn)證碼操作。 完成這些步驟后,

    2023年04月21日
    瀏覽(23)
  • 使用Python編寫一個多線程的12306搶票程序

    國慶長假即將到來,大家紛紛計(jì)劃著自己的旅行行程。然而,對于很多人來說,搶購火車票人們成了一個令人頭疼的問題。12306網(wǎng)站的服務(wù)器經(jīng)常因?yàn)榱髁扛叨罎ⅲ瑢?dǎo)致?lián)屍弊兊迷絹碓絿?yán)重異常困難。 首先,讓我們來了解一下12306搶票的難點(diǎn)。由于很多人都在同一時間段內(nèi)

    2024年02月07日
    瀏覽(28)
  • 爬蟲練習(xí)-12306自動購票升級版

    爬蟲練習(xí)-12306自動購票升級版

    hello兄弟們,偷懶歸來了。別問為啥這么久沒更,問就是失蹤了 最近一直在學(xué)習(xí)Django以及爬蟲進(jìn)階之類的知識,加上快期末了,一直沒有想起來自己還有一個賬號沒有更新,sorry啦 言歸正傳,今天抽空把前面的文章升級了一下。這里先把整理好的代碼提前放給大家 代碼放上,

    2024年02月06日
    瀏覽(54)
  • chatgpt賦能python:Python自動搶票:讓你的購票經(jīng)歷更加簡單便捷!

    隨著互聯(lián)網(wǎng)的發(fā)展,越來越多的人選擇在網(wǎng)上購買火車、飛機(jī)等交通工具的票。但是,一些火爆的車次、航班往往在開售后僅僅幾秒鐘內(nèi)就被搶完,讓很多想出行的人非??鄲?。在這種情況下,Python自動搶票就成了很多人的“救星”。 Python自動搶票是指利用Python編程軟件,通

    2024年02月15日
    瀏覽(22)
  • 爬蟲日常練習(xí)-selenium登錄12306

    爬蟲日常練習(xí)-selenium登錄12306

    hello,好兄弟們。經(jīng)過前面幾篇文章后,想必小伙伴們對于簡單的網(wǎng)頁文本爬取,圖片爬取類的內(nèi)容已經(jīng)熟練掌握了。今天我們開始練習(xí)一個新的內(nèi)容:selenium。有關(guān)這一塊的基礎(chǔ)知識網(wǎng)上太多了,我們作為進(jìn)階的練習(xí)文章就不在這里從基礎(chǔ)說起了。直接上實(shí)際案例,與大家分

    2024年02月05日
    瀏覽(18)
  • 爬蟲日常-selenium登錄12306,繞過驗(yàn)證

    爬蟲日常-selenium登錄12306,繞過驗(yàn)證

    hello兄弟們,這里是無聊的網(wǎng)友。愉快的周末過去了,歡迎回到學(xué)習(xí)頻道。書接上文,我們說到了再用selenium登錄12306時遇到了滑塊驗(yàn)證的問題。當(dāng)前的網(wǎng)站幾乎每家都會在登錄模塊添加一個認(rèn)證,來規(guī)避各種爬蟲,而我們則不斷的去想辦法繞過這些驗(yàn)證模塊。目前一些簡單的

    2024年02月07日
    瀏覽(94)
  • Python 大麥搶票腳本

    請注意,編寫或使用搶票腳本可能違反相關(guān)網(wǎng)站的服務(wù)條款和法律法規(guī)。以下內(nèi)容僅供學(xué)習(xí)和了解技術(shù)原理之用,不鼓勵或支持任何違反規(guī)定的行為。 在Python中編寫大麥網(wǎng)搶票腳本通常涉及以下幾個步驟: ### 1. 分析網(wǎng)站結(jié)構(gòu) - 使用瀏覽器的開發(fā)者工具(如Chrome的Inspect功能)

    2024年04月12日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包