python实战扫码下载_Python实例 一 12306抢票(一)扫码登陆
一、登陸
采用掃碼二維碼的方式登陸,就是得下個app。。? 驗證碼太煩了,不想搞
1.獲取二維碼:
先分析二維碼一般是一張圖片,我們把他下載到本地 來方便掃碼
圖片還是base64的數(shù)據(jù)形式
但是我們用傳統(tǒng)的方式爬下來 并不能取到圖片的信息,只有一個圖片占位標簽
拿到的東西沒有src內(nèi)容 但是頁面上卻有,說明圖片的url是動態(tài)獲取填充的
(用到了SoupStrainer庫安裝pip install beautifulSoup4,介紹:開坑中 )
繼續(xù)分析,發(fā)現(xiàn)有這樣一個請求,可以拿到圖片的src內(nèi)容
圖片是base64形式存儲的 可以直接把他保存為圖片 (base64:二進制編碼數(shù)據(jù)形式,圖片存數(shù)據(jù)庫一般就這樣放,取出來解析就是一張圖,但是一般會比較長。。 )
需要用到一個庫操作圖片pip install pillow
由于圖片是base64 還需要引入base64的庫解碼
模擬請求,下載圖片:
參數(shù):{appid:otn} //固定的
返回:
```
{"result_message":"生成二維碼成功","result_code":"0","image":"iVBORw0KGgoAAAANSUhEUgAAAMcAAA......","uuid":"4B-aKlPZTyR4xlPGh7wmTz553-0ep8w-Lufw8sVxCir-mcQuzTf9iZPX-M4OZYBWjRiASiGJaiv0we1"}
```
代碼:
```
import?base64
import?json
import?os
import?re
import?requests??#?用requests庫,方便保存會話?功能和urllib差不多
from?bs4?import?BeautifulSoup,?SoupStrainer??#?網(wǎng)頁解析庫?可以替代正則來獲取你想要的內(nèi)容
from?PIL?import?Image??#?操作圖片
session?=?requests.Session()?#?session會話對象,請求和返回的信息保存在session中
def?get(url):
header?=?{
"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/67.0.3396.99?Safari/537.36",
}
reqs?=?session.get(url,?headers=header)
return?reqs.text
def?post(url,?data):
header?=?{
"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/67.0.3396.99?Safari/537.36",
}
reqs?=?session.post(url,?headers=header,?data=data)
return?reqs.text
#獲取二維碼圖片
def?getQR():
data?=?post(
'https://kyfw.12306.cn/passport/web/create-qr64',?{"appid":?"otn"})
json_result?=?json.loads(data)?#?是json格式?直接轉(zhuǎn)成json方便操作
print(json_result)
if(json_result['result_code']?==?"0"):
login_pic?=getImage(base64.b64decode(json_result['image']))
Image.open(login_pic).show()?#依賴PIL庫,打開圖片(會創(chuàng)建一個零食文件打開圖片,圖片未被占用時銷毀)
def?getImage(img):
filepath?=?'./login.png'
with?open(filepath,?'wb')?as?fd:?#w寫入?b二進制形式
fd.write(img)
return?filepath
if?__name__?==?"__main__":
getQR()
```
結(jié)果
搞定 圖片拿回來了。
2.登陸掃碼
圖片是拿回來了也可以掃了,然而掃完之后并沒有什么反應(yīng)啊。。
繼續(xù)分析! 12306是如何知道我們已經(jīng)掃碼了?
在上一步我們分析拿二維碼的時候 應(yīng)該有注意到,請求中不止一個二維碼的,還有一個大概每秒一個的請求
就是這個checkqr根據(jù)字面意思,檢查二維碼!!
我們掃一掃二維碼 再看返回內(nèi)容? 注意result_code從0變成了1?!!
點擊確定登陸再看(勾上preserve log 不然跳轉(zhuǎn)了日志就沒了)
??
chrome的弊端。。 看不了了 可以用火狐看
搞定!?result_code為?2時,說明掃碼成功,token? get√!!
用程序來模擬這個請求:
地址:https://kyfw.12306.cn/passport/web/checkqr
參數(shù):{
uuid:"", //這個參數(shù)在前面取二維碼時,有同時返回回來的
appid:otn 固定的
}
返回:
```
{'result_message':?'掃碼登錄成功',?'result_code':?'2',?'uamtk':?'1bzmt2A2uZNXk96zw1kwAypjB4m3DzjQease2oBSTCYjnq2q0'}
```
代碼:
```
import?base64
import?json
import?os
import?re
import?time
import?requests??#?用requests庫,方便保存會話?功能和urllib差不多
from?bs4?import?BeautifulSoup,?SoupStrainer??#?網(wǎng)頁解析庫?可以替代正則來獲取你想要的內(nèi)容
from?PIL?import?Image??#?操作圖片
import?threading
session?=?requests.Session()??#?session會話對象,請求和返回的信息保存在session中
def?get(url):
header?=?{
"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/67.0.3396.99?Safari/537.36",
}
reqs?=?session.get(url,?headers=header)
return?reqs.text
def?post(url,?data):
header?=?{
"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/67.0.3396.99?Safari/537.36",
}
reqs?=?session.post(url,?headers=header,?data=data)
return?reqs.text
#?獲取二維碼圖片
def?getQR():
data?=?post(
'https://kyfw.12306.cn/passport/web/create-qr64',?{"appid":?"otn"})
json_result?=?json.loads(data)??#?是json格式?直接轉(zhuǎn)成json方便操作
if(json_result['result_code']?==?"0"):
uuid?=?json_result['uuid']
threading._start_new_thread(checkqr,(uuid,))?#?開一個線程去執(zhí)行監(jiān)聽
login_pic?=?getImage(base64.b64decode(json_result['image']))
Image.open(login_pic).show()??#?依賴PIL庫,打開圖片(會創(chuàng)建一個零食文件打開圖片,圖片未被占用時銷毀)
def?getImage(img):
filepath?=?'./login.png'
with?open(filepath,?'wb')?as?fd:??#?w寫入?b二進制形式
fd.write(img)
return?filepath
def?checkqr(uuid):
while(True):
checkqr_url?=?'https://kyfw.12306.cn/passport/web/checkqr'
data?=?post(checkqr_url,?{"uuid":?uuid,?"appid":?"otn"})
json_result?=?json.loads(data)
print(json_result)
status_code?=?json_result['result_code']
if(status_code?==?"1"):
print('已掃描請確定')
elif(status_code?==?"2"):
print(json_result['result_message'])
return
elif(status_code?==?'3'):??#?二維碼過期
getQR()
return
time.sleep(2)
if?__name__?==?"__main__":
getQR()
```
雖然提示掃碼登陸成功,現(xiàn)在調(diào)用檢查是否登陸 可以看到結(jié)果flag是false 代表未登錄? ?↓
(不貼完整代碼了 太長,后面給源碼)
掃碼登陸成功主要是取回token,然后帶著token去請求驗證,可以看到上一個不是掃碼成功的請求里并沒有token
這里有個重要的點!!!,怎么保存會話
我們的請求全是通過seeesion來發(fā)起的,所有如果請求后返回的信息如token,cookie之類,會自動記錄到session中,你再用session來發(fā)起時 會自動帶上請求的cookie之類的信息!
強大!
驗證:
地址:https://kyfw.12306.cn/passport/web/auth/uamtk
參數(shù):{appid:otn} //固定的
返回:
{"result_message":"驗證通過","result_code":0,"apptk":null,"newapptk":"oIxLeXFNNYv1526TDD6Avm-oX3OAmexpa3T6bKVEefg36q2q0"}
地址:https://kyfw.12306.cn/otn/uamauthclient
參數(shù):{tk:""} //驗證1里返回的newapptk
返回:
{"apptk":"oIxLeXFNNYv1526TDD6Avm-oX3OAmexpa3T6bKVEefg36q2q0","result_code":0,"result_message":"驗證通過","username":"XX"}
模擬請求:
可以看到驗證成功之后 返回了你的郵箱或者姓名之類的信息! 再檢查是否登陸 flag:Ture!到此為止 登陸搞定! 算是剝?nèi)ヒ路?/p>
整理下流程:
https://kyfw.12306.cn/passport/web/create-qr64?//獲取二維碼
https://kyfw.12306.cn/passport/web/checkqr?//檢查二維碼是否過期或是否被掃碼
https://kyfw.12306.cn/passport/web/auth/uamtk?//驗證
https://kyfw.12306.cn/otn/uamauthclient?//二次驗證
總結(jié)
以上是生活随笔為你收集整理的python实战扫码下载_Python实例 一 12306抢票(一)扫码登陆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 写一个上班看股票的小软件
- 下一篇: scum服务器设置网站,SCUM服务器配