Python-又到了抢票的季节(带验证码识别验证)
生活随笔
收集整理的這篇文章主要介紹了
Python-又到了抢票的季节(带验证码识别验证)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言:
初入Python,打算搞個練手項目,正巧又到了搶票的季節,那就12306了,反正也早就被玩壞了,哈哈哈哈。。。由于是邊練手邊寫的,為了方便,沒有啥優雅的姿勢,每個功能一個方法大概如下:
1.獲取登錄需要的驗證碼圖片保存到本地 2.自動識別驗證碼(或手動識別) 3.驗證驗證碼并登錄 4.多重驗證(驗證之后才能獲取真正的登錄狀態) 5.掃票 6.下訂單 7.獲取聯系人 8....大概是這么個樣子,那么就開始吧~~~~~~~~ 復制代碼直奔主題:
用到的包: import json import random import re import time import requests 復制代碼第一步:獲取驗證碼圖片保存到本地
# 首先為了之后能保持登錄狀態,我們要先弄一個全局的會話,以后的session都是這個了 session = requests.session() # 獲取驗證碼圖片并保存 def get_code():# 這是驗證碼圖片接口 后面是個隨機數code_url = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&{}'.format(str(random.random()))r = session.get(code_url)with open('code.png', 'wb') as f:f.write(r.content)print('獲取驗證碼并保存成功') 復制代碼第二步:獲取驗證碼的正確坐標
首先我們看到保存的驗證圖片如下(已打上編號):
那么就先說下手動驗證,就是用你的鈦合金狗眼分辨上圖 然后輸入:4 6 # 對8個小圖坐標化,因為最終驗證接口是得用坐標做參數的,比如上圖對應的參數就應該是: 260,40,110,120 code = ['40,40', '110,40', '180,40', '260,40', '40,120', '110,120', '180,120', '260,120'] # 識別驗證碼 并得到正確坐標 def code_answer():num = input('請輸入:')try:num = [int(num)]except ValueError:num = list(map(int, num.split()))answer = '' # 構建一個空字符串for i in num: # 對驗證碼序號列表進行遍歷answer += code[i - 1] + ',' # 將每個驗證碼序號對應的位置信息添加到字符串中,并加上','號answer_result = answer.rstrip(',')print('得到驗證碼坐標:', answer_result)return answer_result 復制代碼然后就是高科技了,使用一個牛X的網站自動識別(最近不大穩定,可能要多幾次):
# 識別驗證碼 并得到正確坐標 def code_answer():# 自動識別的網站 url = 'http://littlebigluo.qicp.net:47720/'files = {'file': open('code.png', 'rb')}r = session.post(url, files=files)num = r.text.split('<B>')[1].split('<')[0]#其實也就是上面這塊獲取 num 手動改成自動了 有興趣的朋友可以做個判斷,自動不穩定時提醒手動輸入try:num = [int(num)]except ValueError:num = list(map(int, num.split()))print(num)answer = '' # 構建一個空字符串for i in num: # 對驗證碼序號列表進行遍歷answer += code[i - 1] + ',' # 將每個驗證碼序號對應的位置信息添加到字符串中,并加上','號answer_result = answer.rstrip(',')print('得到驗證碼坐標:', answer_result)return answer_result 復制代碼第三步:驗證驗證碼并登錄
def check_and_login():# 如果之前沒加 User-Agent 這里加一下headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}# 驗證驗證碼的接口check_url = 'https://kyfw.12306.cn/passport/captcha/captcha-check'# 登錄接口login_url = 'https://kyfw.12306.cn/passport/web/login'# 驗證參數check_data = {'answer': code_answer(),# 這里就是上面我們得到的驗證碼坐標'login_site': 'E','rand': 'sjrand'}# 登錄參數login_data = {'username': '12306賬號','password': '12306密碼','appid': 'otn'}print('開始驗證驗證碼...')check_r = session.post(check_url, data=check_data, headers=headers, verify=False) # 注意關掉SSL驗證check_result = json.loads(check_r.text)if check_result['result_code'] == '4': # 4代表成功,5代表驗證碼錯誤,8代表驗證信息為空print(check_result['result_message'])login_r = session.post(login_url, data=login_data, headers=headers, verify=False)login_result = json.loads(login_page.text)print(login_result)# 這里就是表面上登錄成功了,但是是得不到用戶信息得,還得需要多次驗證validate_apptk(get_apptk()) # 獲取tk并驗證tkisLogin() # 驗證登錄 如果正確 返回帶有實名的結果 至此登錄完成else:print('驗證失敗,開始重新驗證')get_code()check_and_login()return 復制代碼第四步:驗證登錄
# 首先獲取一個 apptk def get_apptk():url = 'https://kyfw.12306.cn/passport/web/auth/uamtk'data = {'appid': 'otn'}r = session.post(url, data=data)result = json.loads(r.text)return result['newapptk'] # tk驗證 把上面獲取到的 apptk Post去驗證 def validate_apptk(newapptk):url = 'https://kyfw.12306.cn/otn/uamauthclient'data = {'tk': newapptk}r = session.post(url, data=data)result = json.loads(r.text)print('postTk', result) # 最后驗證 def isLogin():url = 'https://kyfw.12306.cn/otn/login/conf'r = session.get(url)result = json.loads(r.text)print(result) # 打印結果 如果結果有 name = 你的實名 則真正登錄成功,接下來就可以用這個保存登錄狀態的session去浪了~ 復制代碼第五步: 下面就是真正的騷操作了
都已經拿到保存登錄狀態的session了,接下來 就是抓接口 去掃票下單了。 接口就不說了,我用的google瀏覽器 打開12306網站 F12 然后正常操作一遍掃票流程,就可以在右找到了。吃飯前給到大家發個紅包 滑稽~滑稽~
轉載于:https://juejin.im/post/5c18be5cf265da610e800541
總結
以上是生活随笔為你收集整理的Python-又到了抢票的季节(带验证码识别验证)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简 易 版 线 程 池 模
- 下一篇: 简析多种编码方式(Hex, Base64