12306搶票系統無介面版本——(1)登入(12306驗證碼問題破解)
引言
隨著高速鐵路時代的來臨,世界發達地區高速鐵路網路的不斷完善與發展,高速鐵路運輸成為各國重要的交通方式之一。同時鐵路的高速發展正在影響著人們的出行方式。
“鐵路12306”是中國鐵路客戶服務中心推出的官方購票應用軟體,與火車票務官方網站共享使用者、訂單和票額等資訊,並使用統一的購票業務規則,軟體具有車票預訂、線上支付、改簽、退票、訂單查詢、常用聯絡人管理、個人資料修改、密碼修改等功能。於2013年12月8日正式上線試執行。而“鐵路12306”雖然滿足了我們基本的購票需要,但是對一些特殊群體並沒有照顧到。為了改變這種情況,為此嘗試使用python程式碼來實現搶票系統。
使用工具和庫
開發環境是python3.6.5
開發工具是sublime Text
使用到的重要庫:
http請求(requests庫)
模擬登入流程
1.進入12306登入網站
首先匯入requests包,利用requests中的Session()保持cookie。
import requests
session = requests.Session()
url = "https://kyfw.12306.cn/otn/login/init"
response = session.get(url)
2.獲取驗證碼
在開發者工具中的Network可以很容易找到其中的驗證碼。從而我們可以得到驗證碼的 Request URL: https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.5516997730666673。
(這個驗證碼是實時重新整理的)
接著上面的的程式碼,我們通過傳送get請求得到驗證碼圖片並儲存。
#下載驗證碼
captcha_url = "https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.3874691076542045"
cap_response = session.get(captcha_url)
#儲存驗證碼 寫檔案
f = open('captcha.jpg','wb')
f.write(cap_response.content) #二進位制資料
f.close()
3.校驗驗證碼
首先嚐試選擇驗證碼並點選。我們可以在Netwrok中看到一個新的響應。
從名字也可以很容易理解這是一個校驗驗證碼的響應。我們把Headers拉到最下面可以看到通過傳送POST請求來校驗驗證碼是否正確。
這其中的answer就是我們選擇驗證碼之後的位置。
下面是程式碼實現。
#校驗驗證碼
check_url = "https://kyfw.12306.cn/passport/captcha/captcha-check"
'''
Form Data
answer: 168,45
login_site: E
rand: sjrand
'''
point = {
'1': '35,43',
'2': '108,43',
'3': '185,43',
'4': '254,43',
'5': '34,117',
'6': '108,117',
'7': '180,117',
'8': '258,117',
}
#可以確定八個圖片的位置
def get_point(nums):
nums = nums.split(',')
# print(nums)
temp = []
for item in nums: # ['3', '6']
temp.append(point[item])
return ','.join(temp)
data = {
'answer': get_point(input('請輸入驗證碼座標:')), #'254,106'
'login_site': 'E',
'rand': 'sjrand'
}
check_response = session.post(check_url,data=data)
# print(check_response.text)
check_res = check_response.json()
# 判斷校驗結果
if not check_res['result_code'] == '4':
exit('驗證碼校驗失敗,請重新登入')
最後我們通過驗證”result_code”是否等於4來判斷驗證碼是否選擇正確。
4.登入,校驗使用者名稱和密碼
假如我們嘗試選擇正確的驗證碼登入,會發現12306是先驗證驗證碼是否正確再去校驗使用者名稱或者密碼。
通過跟驗證碼同樣的方式,我們首先選擇正確的驗證碼,輸入使用者名稱和密碼後點選登入會發現得到了新的響應。
這裡也很容易理解,瀏覽器得到賬號和密碼之後傳送了一個表單給Request URL: https://kyfw.12306.cn/passport/web/login。
用與驗證碼類似的方法來寫程式碼。
# 登入 ,校驗使用者名稱和密碼
import config
login_url = 'https://kyfw.12306.cn/passport/web/login'
login_data = {
"username": config.username,
"password": config.password,
"appid": "otn"
}
login_response = session.post(login_url,data=login_data)
這裡我新寫了一個程式碼來呼叫使用者名稱和密碼。
到這裡我們差不多完成了驗證碼問題和登入問題。
當時我也簡單的認為這裡已經登入全部完成。但是之後測試時發現得到的網頁中沒有顯示個人的名字。通過再次檢查發現登入完成後還傳送了兩個請求得到許可權來完整的完成登入。
4.獲取許可權
經過反覆測試之後發現需要兩個請求來獲取許可權。
首先我們傳送請求到uamk中,FortData為:
#獲取許可權
uamtk_url = 'https://kyfw.12306.cn/passport/web/auth/uamtk'
uamtk_data = {
'appid': 'otn'
}
response = session.post(uamtk_url, data=uamtk_data)
print(response.text)
uantk_response = response.json()['newapptk']
我們嘗試輸出得到的返回值,發現其中的”newapptk”就是第二個請求傳送的表單內容
所以我們定義一個變數來儲存這個值。再將它傳送給”uamauthclient”中。
# 獲取許可權
auth_url = 'https://kyfw.12306.cn/otn/uamauthclient'
auth_data = {
'tk': uantk_response
}
response = session.post(auth_url, data=auth_data)
if response.json()['result_code'] == 0:
print(response.text)
完成這兩步之後我們輸出返回值。可以看到這裡輸出了我們使用者的姓名。
5.跳轉頁面
# 跳轉登陸頁面
login_redirect = 'https://kyfw.12306.cn/otn/login/userLogin'
response = session.get(login_redirect)
check_url = 'https://kyfw.12306.cn/otn/login/checkUser'
data = {
'_json_att': ''
}
response = session.post(check_url,data=data)
# print(response.text)
假如我們嘗試輸出可以得到使用者的姓名來驗證是否已經獲取許可權並登入成功。
到此為止我們已經完整的完成了登入過程。之後便是購票等步驟。
下面附上程式碼執行的結果。
測試完成後我們將整個程式碼進行封裝。
import requests
import random
import config
class TicketRob:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
})
self.index_url = 'https://kyfw.12306.cn/otn/login/init'
self.captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image'
self.login_url = 'https://kyfw.12306.cn/passport/web/login'
self.check_captcha_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'
self.uamtk_url = 'https://kyfw.12306.cn/passport/web/auth/uamtk'
self.auth_url = 'https://kyfw.12306.cn/otn/uamauthclient'
self.point = {
'1': '35,43',
'2': '108,43',
'3': '185,43',
'4': '254,43',
'5': '34,117',
'6': '108,117',
'7': '180,117',
'8': '258,117',
}
self.dict = {}
def get_point(self, nums):
nums = nums.split(',')
# print(nums)
temp = []
for item in nums: # ['3', '6']
temp.append(self.point[item])
return ','.join(temp)
# 檢查使用者名稱密碼
def main(self, username, password):
data = {
'username': username,
'password': password,
'appid': 'otn'
}
self.session.get(self.index_url) # 1
self.get_captcha() # 2
check_res = self.check_captcha() # 3
if check_res:
response = self.session.post(self.login_url, data=data) # 4
if response.json()['result_code'] == 0:
tk = self.get_tk() # 5
auth_res = self.get_auth(tk) # 6
# 獲取驗證碼
def get_captcha(self):
data = {
'login_site': 'E',
'module': 'login',
'rand': 'sjrand',
str(random.random()): ''
}
response = self.session.get(self.captcha_url, params=data)
with open('captcha.jpg', 'wb') as f:
f.write(response.content)
# 校驗驗證碼
def check_captcha(self):
data = {
'answer': self.get_point(input('請輸入正確的圖片序號>>>:')),
'login_site': 'E',
'rand': 'sjrand'
}
response = self.session.post(self.check_captcha_url, data=data)
if response.json()['result_code'] == '4':
return True
else:
print('驗證碼選擇錯誤,請重新選擇')
return False
# 獲取許可權token
def get_tk(self):
uamtk_data = {
'appid': 'otn'
}
response = self.session.post(self.uamtk_url, data=uamtk_data)
return response.json()['newapptk']
# 獲取許可權
def get_auth(self, tk):
auth_data = {
'tk': tk
}
response = self.session.post(self.auth_url, data=auth_data)
if response.json()['result_code'] == 0:
print(response.text)
return True
return False
if __name__ == '__main__':
ticket = TicketRob()
ticket.main(config.username, config.password)
相關文章
- 12306自動搶票及自動識別驗證碼功能(二)
- 最新12306搶票爬蟲爬蟲
- PostgreSQL與12306搶火車票的思考SQL
- Python學習筆記之12306搶票Python筆記
- selenium模擬登入12306
- Python3.6實現12306火車票自動搶票Python
- 12306火車票搶票Python程式碼最新完整版釋出,五一搶票就靠它了!Python
- 從零實現一款12306搶票軟體
- 教你用Python動重新整理搶12306火車票,附原始碼!Python原始碼
- 12306 出招搶票軟體,技術黃牛生意要“黃”?
- 12306購票送溫暖
- 【分散式限流】你被12306的驗證碼坑過麼?分散式
- Emlog漏洞————Emlog部落格系統後臺無視驗證碼暴力破解實現登入
- 爬蟲模擬登入破解無原圖滑動驗證碼爬蟲
- 搶票軟體不靠譜?不如看看用AI怎麼玩轉12306AI
- 使用Python編寫一個多執行緒的12306搶票程式Python執行緒
- 12306候補購票怎麼用?12306火車票候補購票使用攻略和注意事項
- 全網首發:12306搶票演算法大曝光?(十張圖搞定)演算法
- teams 更改密碼後無法登入,提示使用 Microsoft Authenticator 驗證問題密碼ROS
- win10怎麼安裝12306證書_win10如何新增12306證書服務Win10
- 12306對第三方搶票軟體實施限制 平臺:可正常搶票 未受限制
- 登入驗證碼生成kaptcha(輸入驗證碼)APT
- Python暴力破解網站登入密碼(帶token驗證)Python網站密碼
- 直播系統程式碼,登入時常用驗證方式實現
- 是程式設計師就用Python查12306的票程式設計師Python
- 支付寶隨心乘禮包在哪搶?12306隨心乘的搶購方法
- java視窗登入介面實現隨機驗證碼Java隨機
- 織夢後臺登入成功又跳轉回登入介面與驗證碼
- 12306崩了?部分使用者反映無法購票 網友集體炸鍋
- 解決 PBootCMS 後臺登入不顯示驗證碼的問題boot
- uniapp 完成兩種方式登入 驗證碼登入 密碼登入APP密碼
- 12306本週起試點候補購票 每人可提交1個訂單訂3張票
- 父子元件通訊——模擬12306購票新增乘車人元件
- 高併發!一個仿 12306 鐵路購票專案!
- app直播原始碼,登入時輸入驗證碼、簡訊驗證身份APP原始碼
- 使用 jQuery, Angular.js 實現登入介面驗證碼詳解jQueryAngularJS
- 鐵路12306:2024年國慶假期鐵路12306已累計售出黃金週運輸期間車票1.64億張
- Laravel-admin 登入新增驗證碼Laravel