Python爬蟲倒立文字驗證碼登入知乎
阿新 • • 發佈:2019-01-28
引言
本文解析了知乎倒立文字驗證碼的原理,人工識別倒立文字所在位置後組織報文成功登入。
原理
關於登入的基本原理可參考Python爬蟲之模擬知乎登入,只不過這篇文章中登入的驗證碼為“數字英文”模式,而當前登入時是“點選倒立文字”模式,所以主要記錄這部分。
先故意選錯驗證碼,如圖,選中第三個和第五個漢字,點選登入
在開發者模式中觀察瀏覽器是如何傳送請求的
如圖所示captcha即為驗證碼資訊:其中”img_size”欄位每次都是[200,44],應該表示圖片大小。後面的”input_points”是你點選驗證碼中倒立文字的座標,服務端應該是判斷輸入的座標在匹配的一定範圍內即判斷驗證碼正確。
由於驗證碼中七個文字位置是固定的,只需要提前確定每個字所在座標並放入列表中,然後人工確定倒立文字的文字序號,將列表中序號對應的座標加入input_points欄位。
python爬蟲scrapy框架——人工識別登入知乎倒立文字驗證碼和數字英文驗證碼(1)中獲取了這七個文字座標依次如下:[22.796875,22],[42.796875,22],[63.796875,21],[84.796875,20],[107.796875,20],[129.796875,22],[150.796875,22]。
程式碼
# encoding: utf-8
# !/usr/bin/env python
import time
from http import cookiejar
import json
import requests
from bs4 import BeautifulSoup
headers = {
"Host": "www.zhihu.com",
"Referer": "https://www.zhihu.com/",
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}
# 使用登入cookie資訊
session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='cookies.txt')
try:
print(session.cookies)
session.cookies.load(ignore_discard=True)
except:
print("還沒有cookie資訊")
def get_xsrf():
response = session.get("https://www.zhihu.com", headers=headers, verify=False)
soup = BeautifulSoup(response.content, "html.parser")
xsrf = soup.find('input', attrs={"name": "_xsrf"}).get("value")
return xsrf
def get_captcha():
"""
把驗證碼圖片儲存到當前目錄,手動識別驗證碼
"""
t = str(int(time.time() * 1000))#驗證碼是按時間戳命名
captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + "&type=login&lang=cn"
print(captcha_url)
r = session.get(captcha_url, headers=headers)
with open('captcha.gif', 'wb') as f:
f.write(r.content)
f.close()
# 自動開啟剛獲取的驗證碼
from PIL import Image
try:
img = Image.open('captcha.gif')
img.show()
img.close()
except:
pass
captcha = {
'img_size': [200, 44],
'input_points': [],
}
points = [[22.796875, 22], [42.796875, 22], [63.796875, 21], [84.796875, 20], [107.796875, 20],
[129.796875, 22], [150.796875, 22]]
seq = input('請輸入倒立字的位置\n>')
for i in seq:
captcha['input_points'].append(points[int(i) - 1])
return json.dumps(captcha)
def login(email, password):
login_url = 'https://www.zhihu.com/login/email'
data = {
'email': email,
'password': password,
'_xsrf': get_xsrf(),
"captcha": get_captcha(),
'captcha_type': 'cn',}
print(session.cookies)
response = session.post(login_url, data=data, headers=headers)
login_code = response.json()
print(login_code['msg'])
print(session.cookies)
r = session.get("https://www.zhihu.com/settings/profile", headers=headers)
print(r.status_code)
print(r.text)
with open("xx.html", "wb") as f:
f.write(r.content)
if __name__ == '__main__':
email = "xxxxxx"
password = "xxxxxx"
login(email, password)
效果如下: