7 回复
是 form,不是 from …
要模拟登录知乎,核心是处理其登录接口和反爬机制。这里提供一个基于 requests 和 execjs 的完整方案,直接模拟密码登录流程。
import requests
import execjs
import re
import json
class ZhihuLogin:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Host': 'www.zhihu.com',
'Origin': 'https://www.zhihu.com',
'Referer': 'https://www.zhihu.com/signin'
})
def get_captcha(self):
"""获取验证码(如果需要)"""
import time
timestamp = str(int(time.time() * 1000))
url = f'https://www.zhihu.com/api/v3/oauth/captcha?lang=en&t={timestamp}'
resp = self.session.get(url)
if json.loads(resp.text).get('show_captcha'):
# 需要验证码,这里返回图片URL
captcha_url = f'https://www.zhihu.com/api/v3/oauth/captcha?lang=en'
img_resp = self.session.get(captcha_url)
# 实际使用时应保存图片并人工识别
return True
return False
def get_signature(self):
"""生成签名参数(知乎登录需要)"""
with open('zhihu_encrypt.js', 'r', encoding='utf-8') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
signature = ctx.call('getSignature')
return signature
def login(self, username, password):
# 1. 获取登录页面提取_xsrf
home_page = self.session.get('https://www.zhihu.com/signin')
xsrf = re.search(r'_xsrf=([^;]+)', home_page.headers.get('Set-Cookie', '')).group(1)
# 2. 检查验证码
if self.get_captcha():
captcha = input('请输入验证码:')
else:
captcha = ''
# 3. 准备登录参数
login_url = 'https://www.zhihu.com/api/v3/oauth/sign_in'
params = {
'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
'grant_type': 'password',
'source': 'com.zhihu.web',
'username': username,
'password': password,
'lang': 'en',
'ref_source': 'homepage',
'utm_source': ''
}
# 4. 添加签名和headers
signature = self.get_signature()
headers = {
'x-zse-83': '3_2.0',
'x-zse-86': '1.0_' + signature,
'x-xsrftoken': xsrf
}
# 5. 发送登录请求
resp = self.session.post(login_url, data=params, headers=headers)
result = resp.json()
if 'error' in result:
print(f'登录失败: {result.get("error", {}).get("message")}')
return False
else:
print('登录成功!')
# 保存cookies供后续使用
cookies = self.session.cookies.get_dict()
with open('zhihu_cookies.json', 'w') as f:
json.dump(cookies, f)
return True
# 需要配套的JavaScript加密文件(zhihu_encrypt.js)
"""
// 知乎登录参数加密逻辑(简化示例)
function getSignature() {
// 实际需要实现知乎的完整加密算法
// 这里只是示例结构
var timestamp = Date.now();
var msg = 'dontbeanonymous' + timestamp;
// 实际应使用CryptoJS等库进行HMAC-SHA256加密
return btoa(msg);
}
"""
if __name__ == '__main__':
zhihu = ZhihuLogin()
zhihu.login('your_username', 'your_password')
关键点说明:
- 需要先获取
_xsrftoken 作为防跨站请求伪造 - 知乎登录参数需要特定格式的签名(
x-zse-86头) - 验证码系统可能随机触发
- 实际签名算法较复杂,需要逆向分析知乎的JavaScript代码
注意: 完整实现需要分析知乎网页端的加密逻辑,上述代码中的 getSignature() 函数需要根据实际加密算法补充完整。建议使用浏览器开发者工具监控登录请求,复制完整的请求参数和headers。
总结: 逆向分析登录流程是关键。
所以我一般 selenium 登陆拿到 cookie,再 requests 为所欲为
from ???是 form 吧。。。
完了完了,乎 B 又要改算法了
全文的 fromdata 看得我头皮发麻,能不能改一改
不改了,将就点吧,差不了多少

