使用Python requests POST遇422错误,如何无需Selenium实现需登录网站登录?
解决登录需认证网站时的422错误(无需Selenium)
我之前也碰到过类似的问题,422 Unprocessable Entity本质是服务器认为你的请求数据有问题——要么缺参数、参数格式不对,要么触发了反爬机制。针对你爬取类似GitHub网站的场景,咱们一步步来排查解决:
首先,最容易踩的坑:POST目标URL错误
你当前的代码是POST到https://github.com/login,但实际上GitHub的登录表单提交地址是https://github.com/session(大部分网站的表单action都不是当前页面URL)。这是导致422的常见原因之一。
其次,模拟真实浏览器的请求头
requests默认的请求头太“朴素”,很容易被服务器识别为非浏览器请求。你需要添加必要的headers,比如User-Agent、Referer、Accept等,模拟真实浏览器的请求。
然后,确保表单数据完整且正确
除了login和password,服务器通常还需要CSRF token等隐藏字段。你之前提取隐藏字段的思路是对的,但要确保xpath能准确匹配到登录表单的隐藏字段(比如限定form的action属性)。
修正后的完整代码示例
import requests from lxml import html # 配置你的账号信息和目标地址 LOGIN_PAGE_URL = "https://github.com/login" LOGIN_SUBMIT_URL = "https://github.com/session" # 正确的提交地址 USER_EMAIL = "your_email@example.com" USER_PASSWORD = "your_password_here" TARGET_PROFILE_URL = "https://github.com/your_username" # 用来验证登录的页面 # 初始化会话,自动处理cookie session = requests.Session() # 第一步:获取登录页面,提取表单所需的隐藏字段和cookie login_page_response = session.get(LOGIN_PAGE_URL) page_tree = html.fromstring(login_page_response.content) # 提取登录表单内的所有隐藏字段(限定form的action为/session,避免匹配到其他表单) form_data = {} for hidden_input in page_tree.xpath('//form[@action="/session"]//input[@type="hidden"]'): form_data[hidden_input.attrib["name"]] = hidden_input.attrib["value"] # 添加登录凭证到表单数据 form_data["login"] = USER_EMAIL form_data["password"] = USER_PASSWORD # 构建模拟浏览器的请求头,这些字段可以从浏览器抓包获取 request_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Referer": LOGIN_PAGE_URL, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3" } # 第二步:发送登录请求 login_response = session.post(LOGIN_SUBMIT_URL, data=form_data, headers=request_headers) # 第三步:验证登录是否成功 profile_response = session.get(TARGET_PROFILE_URL) if "your_username" in profile_response.text: print("✅ 登录成功!") else: print(f"❌ 登录失败,状态码:{login_response.status_code}")
其他可能的问题排查
如果上面的代码还是不行,你需要用浏览器的开发者工具抓包对比:
- 打开浏览器F12,切换到「Network」标签,勾选「Preserve log」
- 手动登录一次,找到登录的POST请求(比如GitHub的是
session) - 对比你的请求和真实请求的Form Data、Request Headers,找出差异:
- 是否有遗漏的表单字段(比如
timestamp、timestamp_secret这类动态生成的字段) - 请求头是否缺少关键字段(比如
Cookie里的特定值) - 密码是否需要前端加密(部分网站会在前端对密码进行哈希处理后再提交)
- 是否有遗漏的表单字段(比如
另外,如果你的账号开启了两步验证(2FA),还需要额外处理验证码,这时候可以借助OTP生成库(比如pyotp)来生成验证码并添加到表单数据中。
内容的提问来源于stack exchange,提问作者JonasUJ
相关产品推荐
相关产品推荐

