使用Requests提交表单却返回原始页面的问题排查求助
兄弟,我太懂你这种手动提交正常、代码跑出来却拿不到预期结果的憋屈了!结合你遇到的情况,大概率是这些细节没处理到位,咱们一步步排查:
1. 确认请求方法与提交URL是否正确
首先得搞清楚网页表单是用GET还是POST提交的,以及表单的action属性指向的真实处理URL(不一定是当前页面URL)。你可以打开浏览器开发者工具(F12),在手动提交表单时看「网络」标签里的请求:
- 看请求的方法是POST还是GET
- 复制请求的目标URL,替换代码里的URL
比如如果表单是POST提交,你却用了requests.get(),那肯定拿不到正确结果。
2. 检查提交参数是否完整(包括隐藏字段)
很多表单会有隐藏字段,比如csrf_token、session_id这类,手动提交时浏览器会自动带上,但代码里如果没加这些参数,服务器就不会认你的请求。同样在开发者工具的请求里,看「表单数据」部分,把所有参数(不管是不是可见的)都复制到代码的参数字典里,一个都不能少。
举个例子,你代码里可能只加了可见的输入参数,但漏掉了像__VIEWSTATE、__EVENTVALIDATION这类ASP.NET常见的隐藏字段,或者csrf token。
3. 添加必要的请求头
很多网站会校验请求头来判断是不是正常浏览器访问,至少要加这几个:
User-Agent:模拟浏览器的标识,比如Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36Referer:告诉服务器你是从哪个页面跳过来的,就是表单所在的页面URL- 有些还需要
Accept、Accept-Language这些头
代码示例:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'Referer': 'https://xxx.com/your-form-page' } response = requests.post(url, data=params, headers=headers)
4. 维护会话(使用Session对象)
手动提交时,浏览器会自动保存服务器返回的Cookie,后续请求会带上这些Cookie。但你的代码如果用普通的requests.get/post,每次请求都是独立的会话,服务器可能认不出你。改用requests.Session()来维护会话:
session = requests.Session() # 先访问表单页面,获取必要的Cookie和隐藏字段 form_page = session.get('https://xxx.com/your-form-page') # 在这里解析form_page的HTML,提取隐藏字段(比如用BeautifulSoup) # 然后提交表单 response = session.post(processing_url, data=all_params, headers=headers)
5. 检查参数编码与格式
有些表单要求参数是特定格式,比如JSON而不是表单数据,或者需要编码特殊字符。如果服务器接收JSON,就要用json=params而不是data=params:
response = session.post(url, json=params, headers=headers)
另外,如果你用了中文或者特殊字符,确保编码正确,requests一般会自动处理,但如果遇到问题,可以手动指定编码。
最后一步:对比请求差异
把代码发送的请求和浏览器手动提交的请求做对比,看哪里不一样。可以用print(response.request.headers)、print(response.request.body)来查看代码发送的内容,和浏览器里的请求头、表单数据逐一比对,肯定能找到差异点!
内容的提问来源于stack exchange,提问作者midwestcoast

