此次是我第一次模擬登入,目標(biāo)站點是知乎。
剛開始在網(wǎng)上看別人一直在說知乎登入首頁有有倒立的漢字驗證碼,我打開自己的知乎登入頁面,發(fā)現(xiàn)只有賬號和密碼,他們說的倒立的驗證碼去哪了,后面仔細(xì)一想我之前登入過知乎,應(yīng)該在本地存在cookies,然后我將cookies刪除掉果然就有需要驗證碼了:
分析-01.png
參考了大多數(shù)的意見,可以模擬登入移動端,驗證碼形式是我們常見的字母數(shù)字組合,避開這個點擊倒立的驗證碼形式,然后我就在移動端抓包了,可以拿到驗證碼圖片的包,我們可以請求這個URL拿到每次的驗證碼:
分析-02.png
這個URL的結(jié)構(gòu)是:https://www.zhihu.com/captcha.gif?r=xxx&type=login
分析-03.png
搜索"<input",可以抓到如下:
分析-04.png
要拿到_xsrf、captcha、phone_num、password這四個參數(shù),然后模擬發(fā)送POST請求,phone_num、password好處理就是登入的手機(jī)號碼和密碼,手動輸入即可。
對于_xsrf,我是利用了正則表達(dá)式來提取,出現(xiàn)的問題:
1、剛開始的URL寫成https://www.zhihu.com/提取不到內(nèi)容,后面把此請求的response打印出來,發(fā)現(xiàn)并不是我們所需要的頁面,后面返回PC端去拿到這個URL,返回我們所需的頁面。
2、正則表達(dá)式匹配的時候總是多匹配了多余的內(nèi)容,同樣在打印出源代碼的時候發(fā)現(xiàn) value="(.*?)"/>有一個/。
def get_xsrf():
url='https://www.zhihu.com/signin?next=/'
html=session.get(url=url,headers=headers).text
pattern=re.compile('.*?<input type="hidden" name="_xsrf" value="(.*?)"/>', re.S)
_xsrf=re.search(pattern,html).group(1)
if _xsrf:
print('_xsrf獲取成功:'+ _xsrf)
return _xsrf
else:
print('_xsrf獲取失敗')
對于captcha,就是驗證碼了,在剛開始的時候也提到了,可以請求相應(yīng)的URL,拿到每次所需的驗證碼,人工來識別驗證碼的好處就是準(zhǔn)確率高,這里我嘗試使用了,人工識別的方法:
驗證碼圖片會下載至項目所在的文件夾,打開圖片,輸入驗證碼即可
def get_captcha():
t=int(time.time()*1000)
url='https://www.zhihu.com/captcha.gif?r='+str(t)+'&type=login'
content=session.get(url=url,headers=headers).content
with open('captcha.jpg','wb') as f:
f.write(content)
im=Image.open('captcha.jpg')
im.show()
time.sleep(5)
im.close()
return input('請輸入驗證碼:')
后面我又嘗試使用OCR(Optical Character Recogintion,光學(xué)字符識別),所用到的包是pytesseract,看能不能夠自動識別,但是顯然效果是很差的,在此也記錄一下:
def get_captcha():
t=int(time.time()*1000)
url='https://www.zhihu.com/captcha.gif?r='+str(t)+'&type=login'
content=session.get(url=url,headers=headers).content
with open('captcha.jpg','wb') as f:
f.write(content)
im=Image.open('captcha.jpg') #把彩色圖像轉(zhuǎn)化成灰度圖像
gray=im.convert('L')
gray.show()
threshold=200 #二值化處理
table=[]
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
out=gray.point(table,'1')
out.show()
out.save('captcha_thresholded.jpg')
th=Image.open('captcha_thresholded.jpg') #使用Tesseract進(jìn)行圖片識別
print(pytesseract.image_to_string(th))
return pytesseract.image_to_string(th)
試了幾次,OCR識別的結(jié)果都是有問題的,結(jié)果是這樣的:
分析-07.png