使用python實現(xiàn)無需驗證碼免登錄12306搶票功能
前言
提示:這里可以添加本文要記錄的大概內容:
就在剛剛我搶的票:2025年1月8日 上午9.00多 搶到了哈哈哈哈— 其實還是有用的我是在 8:59:56運行程序的


上一篇帖子,我們已經了解了如何用python自動登錄12306實現(xiàn)自動搶票,現(xiàn)在我們來一個進階的版本,實現(xiàn)cookie免登錄,這樣可繞過驗證碼實現(xiàn)自動搶票。同時包括環(huán)境如何配置,也在這個帖子里面。
需求:上此的帖子,需要自動登錄,并且需要手機驗證碼,在真實搶票中太過繁瑣,所有我自己也在思索,找了帖子和B站,終于實現(xiàn)了用cookie技術自動免登錄12306。在今天上午9.00 (2025-01-07)搶票(2025-01-21)成功。
如何使用:1.比如9.00正式搶票,可以在8.53左右二維碼掃描登錄,當然是要配合下方程序,這樣9.00可以正式搶票無需登錄,cookie也不會失效。2.直接在8.59.58左右運行此程序,即可。
今日實戰(zhàn):今天運行其實是搶到了,但是他一直在等待,也就是頁面一直停在哪里,其實那個時候你可以用手點擊操作,因為我們是進來了,不需要去管程序的對錯。也就是說,程序幫你操作到哪一步,如果卡住了,直接上手。這也讓我有想做一個多線程的想法,將多線程加入這個程序中。

提示:以下是本篇文章正文內容,下面案例可供參考
一、cookie免登錄
1.cookie的講解: Cookie也被稱為小型文本文件,是由服務器發(fā)送到用戶瀏覽器并保存在用戶計算機或移動設備上的一種數(shù)據(jù)形式。以下是對Cookie的詳細解釋:
定義與工作原理定義:Cookie是網站在用戶瀏覽器中創(chuàng)建和存儲的小型文本文件,用于辨別用戶身份和存儲用戶相關信息。工作原理:當用戶訪問某個網站時,服務器會在用戶的瀏覽器中創(chuàng)建一個Cookie,并將其存儲在用戶的計算機或移動設備上。當用戶再次訪問該網站時,瀏覽器會將Cookie發(fā)送回服務器,服務器通過讀取Cookie中的信息來識別用戶身份或獲取用戶的個性化設置。
2.獲取cookie的代碼如下: 程序運行后會打開登錄界面,然后使用的二維碼登錄。這樣程序可以得到當前的cookie值字段,在cookie失效前無須再進行登錄。
<0001>初始化瀏覽器的函數(shù)— browser_initial():
def browser_initial():
""""
進行瀏覽器初始化
"""
# os.chdir('E:\\pythonwork')
# 1.將加載項配置到啟動瀏覽器中 打開/創(chuàng)建瀏覽器對象
browser = webdriver.Chrome(service=Service(path))
# 2.網址 https://kyfw.12306.cn/otn/resources/login.html -- 登錄界面
# https://kyfw.12306.cn/otn/leftTicket/init 選票界面可以 判斷是否登錄
log_url = 'https://kyfw.12306.cn/otn/resources/login.html'
return log_url, browser
<0002> 獲得cookie的函數(shù)— get_cookies(browser):
def get_cookies(browser):
"""
獲取cookies保存至本地
"""
browser.get(log_url)
time.sleep(15) # 進行掃碼
# selenium_login(browser)
# print("登錄成功")
dictCookies = browser.get_cookies() # 獲取list的cookies
string_Cookies = json.dumps(dictCookies) # 轉換成字符串保存
with open('string_cookies.json', 'w') as f:
f.write(string_Cookies)
print('cookies保存成功!')
if __name__ == "__main__":
log_url, browser = browser_initial()
browser.get(log_url)
# 1.二維碼登錄 保存 -- cookie -- 用完關掉
get_cookies(browser)
運行后就會變成二維碼,找到二維碼,讓手機自動登錄。
用手機掃描即可,這個操作是設置了時間time.sleep(15),你也可以在get_cookies(browser)中修改此代碼,只有自己掃了登錄成功,后續(xù)出現(xiàn)的cookie保存成功,才是最新的cookie值。

二、cookie登錄函數(shù)與自動化 – 可以實現(xiàn)cookie值的匹配–實現(xiàn)自動登錄 – 無須手機驗證碼
1.login_cookie函數(shù)代碼
代碼如下(示例):
def login_cookie(log_url, browser):
"""
從本地讀取cookies并刷新頁面,成為已登錄狀態(tài)
"""
# browser.get(log_url)
with open('string_cookies.json', 'r', encoding='utf8') as f:
listCookies = json.loads(f.read())
# 往browser里添加cookies
for cookie in listCookies:
browser.add_cookie(cookie)
time.sleep(1)
# 如果是已登錄的界面,免登錄應該打開這個界面 https://kyfw.12306.cn/otn/view/index.html
# https://www.12306.cn/index/ --12306官網首頁
browser.get(log_url)
return browser
2.selenium_run(driver)函數(shù)代碼 – 這里是可以到預定,然后搶票成功要10分鐘之內自己付款。
def selenium_run(driver):
# 11.1 選擇出發(fā)的城市--點擊那個框
driver.find_element(by="css selector", value="#fromStationText").click()
# 11.2 選擇出發(fā)的城市--選擇城市
driver.find_element(by="css selector", value="#fromStationText").send_keys(login["from_city"])
# 11.3 選擇出發(fā)的城市--回車確定
driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)
# 12.1 選擇目的的城市--點擊那個框
driver.find_element(by="css selector", value="#toStationText").click()
# 12.2 選擇目的的城市--選擇城市
driver.find_element(by="css selector", value="#toStationText").send_keys(login['to_city'])
# 12.3 選擇目的的城市--回車確定
driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)
# 13.1 選擇出發(fā)的日期--點擊那個框
driver.find_element(by="css selector", value="#train_date").clear()
# 12.2 選擇出發(fā)的日期--選擇城市
driver.find_element(by="css selector", value="#train_date").send_keys(login['train_date'])
# 12.3 選擇出發(fā)的日期--回車確定
driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
# # 12.4 點擊--顯示全部可預訂的車次
# driver.find_element(by="css selector", value="avail_ticket").click()
# 12.5 點擊查詢
driver.implicitly_wait(5)
driver.find_element(by="css selector", value="#query_ticket").click()
# num = int(input('請輸入您想要的車次:'))
# 點擊預訂按鈕 -- 選擇要預定的是第幾躺車 -- 這個代碼沒有問題
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[login['num']].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
# 12.6 點擊想要車次的預定按鈕
driver.find_element(by="css selector", value=f"#{ticket_pre}").click()
# 13.1 勾選想要的乘車人
driver.find_element(by="css selector", value='#normalPassenger_0').click()
# 13.2 提交訂單
driver.find_element(by="css selector", value='#submitOrder_id').click()
driver.implicitly_wait(5)
# 13.3 選擇靠窗的1F的位置 #erdeng1 > ul:nth-child(4) > li:nth-child(2) 是在瀏覽器右鍵copy selector選擇出來的
# # 1F是不可以選中的
driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
# 13.4 再次確認提交
time.sleep(1)
# 如果此處沒有響應多點擊就好 -- 加上 "try -- except"
driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
三、完整的代碼
1.代碼主體
先運行get_cookies(browser),注釋掉后面的兩句代碼,二維碼登錄以后,再注釋掉get_cookies(browser),運行后面兩個即可。
if __name__ == "__main__":
log_url, browser = browser_initial()
browser.get(log_url)
# 1.二維碼登錄 保存 -- cookie -- 用完關掉
get_cookies(browser)
# 2.自動登錄
driver = login_cookie(log_url, browser)
selenium_run(driver)
2.完整代碼
import time
import json
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
path = r'D:\game\chromedriver.exe'
def browser_initial():
""""
進行瀏覽器初始化
"""
# os.chdir('E:\\pythonwork')
# 1.將加載項配置到啟動瀏覽器中 打開/創(chuàng)建瀏覽器對象
browser = webdriver.Chrome(service=Service(path))
# 2.網址 https://kyfw.12306.cn/otn/resources/login.html -- 登錄界面
# https://kyfw.12306.cn/otn/leftTicket/init 選票界面可以 判斷是否登錄
log_url = 'https://kyfw.12306.cn/otn/leftTicket/init'
return log_url, browser
def get_cookies(browser):
"""
獲取cookies保存至本地
"""
browser.get(log_url)
time.sleep(15) # 進行掃碼
# selenium_login(browser)
# print("登錄成功")
dictCookies = browser.get_cookies() # 獲取list的cookies
string_Cookies = json.dumps(dictCookies) # 轉換成字符串保存
with open('string_cookies.json', 'w') as f:
f.write(string_Cookies)
print('cookies保存成功!')
def login_cookie(log_url, browser):
"""
從本地讀取cookies并刷新頁面,成為已登錄狀態(tài)
"""
# 這個是12306的登錄界面 https://kyfw.12306.cn/otn/resources/login.html
# browser.get(log_url)
with open('string_cookies.json', 'r', encoding='utf8') as f:
listCookies = json.loads(f.read())
# 往browser里添加cookies
for cookie in listCookies:
# cookie_dict = {
# 'domain': cookie.get('domain'),
# # "expires": cookie.get('value'),
# 'httpOnly': cookie.get('httpOnly'),
# 'name': cookie.get('name'),
# 'path': cookie.get('path'),
# "sameSite": "Lax",
# 'Secure': cookie.get('Secure'),
# 'value': cookie.get('value'),
# }
browser.add_cookie(cookie)
# browser.refresh()
time.sleep(1)
# 如果是已登錄的界面,可以免登錄直接進 https://kyfw.12306.cn/otn/view/index.html
# https://www.12306.cn/index/ --12306官網首頁
browser.get(log_url)
return browser
def selenium_run(driver):
# 11.1 選擇出發(fā)的城市--點擊那個框
driver.find_element(by="css selector", value="#fromStationText").click()
# 11.2 選擇出發(fā)的城市--選擇城市
driver.find_element(by="css selector", value="#fromStationText").send_keys(login["from_city"])
# 11.3 選擇出發(fā)的城市--回車確定
driver.find_element(by="css selector", value="#fromStationText").send_keys(Keys.ENTER)
# 12.1 選擇目的的城市--點擊那個框
driver.find_element(by="css selector", value="#toStationText").click()
# 12.2 選擇目的的城市--選擇城市
driver.find_element(by="css selector", value="#toStationText").send_keys(login['to_city'])
# 12.3 選擇目的的城市--回車確定
driver.find_element(by="css selector", value="#toStationText").send_keys(Keys.ENTER)
# 13.1 選擇出發(fā)的日期--點擊那個框
driver.find_element(by="css selector", value="#train_date").clear()
# 12.2 選擇出發(fā)的日期--選擇城市
driver.find_element(by="css selector", value="#train_date").send_keys(login['train_date'])
# 12.3 選擇出發(fā)的日期--回車確定
driver.find_element(by="css selector", value="#train_date").send_keys(Keys.ENTER)
# # 12.4 點擊--顯示全部可預訂的車次
# driver.find_element(by="css selector", value="avail_ticket").click()
# 12.5 點擊查詢
driver.implicitly_wait(5)
driver.find_element(by="css selector", value="#query_ticket").click()
# num = int(input('請輸入您想要的車次:'))
# 點擊預訂按鈕 -- 選擇要預定的是第幾躺車 -- 這個代碼沒有問題
# driver.find_element(by="css selector", value='#ticket_65000G279007_01_03 > td.no-br').click()
# //div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]/@id -- 但是selenium的find_elements不可以用@id找到元素。
ticket_list = driver.find_elements(by="xpath", value='//div//tbody[@id="queryLeftTable"]/tr[contains(@id,"ticket")]')
ticket_num = ticket_list[login['num']].get_attribute("id")
ticket_pre = ticket_num + ' > td.no-br'
# 12.6 點擊想要車次的預定按鈕
driver.find_element(by="css selector", value=f"#{ticket_pre}").click()
# 13.1 勾選想要的乘車人
driver.find_element(by="css selector", value='#normalPassenger_0').click()
# 13.2 提交訂單
driver.find_element(by="css selector", value='#submitOrder_id').click()
driver.implicitly_wait(5)
# 13.3 選擇靠窗的1F的位置 #erdeng1 > ul:nth-child(4) > li:nth-child(2) 是在瀏覽器右鍵copy selector選擇出來的
# # 1F是不可以選中的
driver.find_element(by="css selector", value='#erdeng1 > ul:nth-child(4) > li:nth-child(2)').click()
# 13.4 再次確認提交
time.sleep(1)
# 如果此處沒有響應多點擊就好 -- 加上 "try -- except"
# driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
# driver.find_element(by="css selector", value='#qr_submit_id').click()
f = open('login.json', encoding='utf-8').read()
login = json.loads(f)
if __name__ == "__main__":
log_url, browser = browser_initial()
browser.get(log_url)
# 1.二維碼登錄 保存 -- cookie -- 用完關掉
# get_cookies(browser)
# 計算程序運行時間
# start = time.perf_counter()
# 2.自動登錄
driver = login_cookie(log_url, browser)
# # 如果沒有登錄那就自動登錄 -- 然后獲得cookie自動保存
# # if browser.find_element(by="css selector", value="#login_user").text == "登錄":
# # 3.自動買票
selenium_run(driver)
# end = time.perf_counter()
# runTime = end - start
# runTime_ms = runTime * 1000
# # 輸出運行時間
# print("運行時間:", runTime, "秒")
# print("運行時間:", runTime_ms, "毫秒")
3.login.json – 解釋這個文件

圖中字典信息:代表的是地址日期,num代表的是第幾躺車,id_card身份證,后4位。這里面有用賬戶密碼登錄的信息,雖然這里用不上,但是我們上一個帖子是用這個的,所以我把它寫在了一起。
四、總結
1.幾個注意:代碼中的url最好是用登錄成功的頁面,而非登錄頁面。不然會一直顯示要登錄。
log_url = 'https://kyfw.12306.cn/otn/resources/login.html' log_url = 'https://kyfw.12306.cn/otn/leftTicket/init' ##---用這個
2.改進:今天真正的實戰(zhàn)我也挺滿意的就是想著再改進一下,看看多線程是否可以直接搶到。明天就要真正搶票啦 – 給大家看看今天的戰(zhàn)果。

以上就是使用python實現(xiàn)無需驗證碼免登錄12306搶票功能的詳細內容,更多關于python免登錄12306搶票的資料請關注腳本之家其它相關文章!
相關文章
對python數(shù)據(jù)清洗容易遇到的函數(shù)-re.sub bytes string詳解
今天小編就為大家分享一篇對python數(shù)據(jù)清洗容易遇到的函數(shù)-re.sub bytes string詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
python?函數(shù)定位參數(shù)+關鍵字參數(shù)+inspect模塊
這篇文章主要介紹了python?函數(shù)定位參數(shù)+關鍵字參數(shù)+inspect模塊,文章圍繞主題展開詳細的相關資料,具有一定的參考價值,需要的小伙伴可以參考一下2022-05-05

