Python爬蟲:Requests模擬登錄知乎 Matplotlib識別中文倒立驗證碼

先說明一下重點中文驗證碼的問題(這里用的還是人工識別的辦法)。

剛開始用requests登錄知乎的時候,只是簡單地根據不同登錄方式請求的url來用requests傳遞參數請求,然后debug次數多了以后就會一直出錯。如下注釋掉我要post的驗證碼數據,由一個函數調用返回:


先用寫完后的代碼作說明,captcha為驗證碼


pycharm調試模式下response的內容

將msg內容在python shell里print一下就是驗證碼識別失敗,說明這個時候必須將驗證碼數據在登錄表單里post過去。

因為一般瀏覽器登錄以后,都會獲取服務器返回的cookie保存在本地,以后瀏覽器再訪問都會帶上cookie中的信息供服務端識別。這里登錄以后可以保存cookie,用reqeusts庫的會話實例來完成原本requests的函數調用

session = requests.Session()

session.cookies = cookielib.LWPCookieJar(filename="cookies.txt")?? # 指定cookies的保存文件名

以上代碼和調用session.cookies.save()保存cookies還需要cookiejar

(好像有這個庫兼容性問題,用這樣的寫法比較好

try:

??? import cookielib

except:

??? import http.cookiejar as cookielib

另外知乎總會識別請求頭是否有不合法的字段值,比如用戶的請求代理是客戶端瀏覽器還是python代碼,從而拒絕請求,必須在每個請求帶上header, 如:

header = {

"Host": "www.zhihu.com",

"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",

"Referer": "https://www.zhihu.com/"

}

1. 模擬登錄開始:

用requests登錄重要的一個方法就是requests.post(), 參數為目標url和表單數據。在知乎登錄界面,輸入郵箱或者手機號,故意填錯密碼,打開瀏覽器網頁調試器,點擊網絡(network),觀察請求的網頁文件,可以看到http協議的請求頭和響應頭。


郵箱登錄的請求(firefox下)

點擊參數可以看到請求所帶的參數

請求的參數:

_xsrf: 防止跨站腳本攻擊的隨機數

password: 登錄密碼

capatcha_type: 驗證碼類型,這里是cn

email: 登錄郵箱

手機號碼登錄同理,url和表單餐宿略有不同。


主登錄邏輯

正則表達式判斷是哪種登錄方式。現在需要確定_xsrf 和 驗證碼,完成兩個方法來返回。

2. _xsrf比較簡單,用lxml或者beautifulsoup從響應中的html文件解析即可,我這里直接用lxml解析,了解xpath就可以了,和css selector有類似結構。

需要 from lxml import etree

返回_xsrf

3. 獲取中文驗證碼:

先來看下中文驗證碼和什么url或者參數有關:


刷新驗證碼圖片可以看到出現一個GET請求,其請求url為:https://www.zhihu.com/captcha.gif?r=1508680722707&type=login&lang=cn

有過了解易知這個參數r是一個格林威治時間, 由str(int(time.time() * 1000))轉換為字符串,

將其與其他固定參數拼接而成請求url。

需要用到兩個庫pillow和matplotlib(這也是我第一次用matplotlib~)

pillow是python常用的操作圖像的庫,matplotlib功能強大,更像一個繪圖庫。

用requests請求以后保存圖片為以后識別做準備。因為圖片有可能有兩個或一個倒立文字,先用pillow顯示圖片,手動輸入個數,再用matploylib讀入圖像文件,由ginput()函數獲取鼠標點擊的坐標。

這里尤其要注意要用到matplotlib的ion()方法打開interactive模式!因為這個花了好久查資料,因為注意到了代碼在調試模式下才工作,有輸出關于Tkagg的信息,反復看了官方文檔找到: 什么是interactive模式

將坐標與其他信息拼接成字符串傳回。

(原來知乎的請求頭里可以看得見表單數據,現在采用了了gzip編碼,看到的都是亂碼)

Accept-Encodingg:zip, deflate, br

返回captcha數據

4.判斷是否登錄成功

請求私信的url根據返回的status_code即可判斷,也可以下載首頁的HTML看是否登錄。

保存了cookies以后可以不用每次都重新登錄,在.py文件開頭加載進cookies,在cookie過期時效內可以直接登錄

try:

??? session.cookies.load(ignore_discard=True)

except:

??? print("cookie未能加載")


參考:

http://blog.wish7.xyz/2016/11/05/%E7%9F%A5%E4%B9%8E%E7%88%AC%E8%99%AB/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容