Python Requests如何提交多阶段分步表单?
解决多阶段分步表单提交问题
看起来你已经摸清楚了表单的三个阶段和对应的请求方法,但大概率在阶段间的参数传递或者必要隐藏字段的携带上踩了坑。我来帮你一步步梳理和调整:
先理清每个阶段的核心细节
打开浏览器开发者工具(DevTools),除了确认请求方法,还要重点盯这几个点:
- 所有请求参数:预览阶段(第二阶段)和推广阶段(第三阶段)是否需要携带第一阶段的表单数据,或者额外的隐藏字段(比如
stage阶段标识、CSRF令牌、会话关联ID等) - 请求头信息:部分网站会校验
Referer来源页、User-Agent客户端标识,这些都要和浏览器请求保持一致 - 页面源码里的隐藏字段:第一阶段GET请求返回的页面中,通常会生成
<input type="hidden">类型的字段(比如CSRF令牌、阶段标记),这些必须在后续POST请求中一起提交
针对你的代码的具体调整建议
你的现有代码里,第三阶段的session.post(url)完全没带参数,这肯定是问题核心——推广阶段必须传递你选择的操作(比如点击「发送」还是「取消」对应的参数),还要带上必要的隐藏字段。
修改后的示例代码(附关键注释)
import requests # 可选:用BeautifulSoup解析页面提取隐藏字段,需要先安装:pip install beautifulsoup4 from bs4 import BeautifulSoup payload = {'log': "MY_LOG", 'pwd': "MY_PASS"} url = "http://..._id=3" url2 = "http://.../wp-login.php" with requests.Session() as session: # 阶段0:登录,先确认登录成功 res_login = session.post(url2, data=payload) if "登录成功" not in res_login.text: # 替换成实际登录成功的标识文本 print("登录失败,请检查账号密码") exit() # 统一设置请求头,模拟真实浏览器 session.headers.update({ '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': url # 来源页设置为表单页面 }) # 阶段1:提交表单(GET方法) payload_stage1 = { 'adcontact_phone': '123321123', 'adtitle': 'TEST TEST', 'addetails': 'TEST TEST' } res_stage1 = session.get(url, params=payload_stage1) # 从阶段1的页面中提取隐藏字段(比如CSRF令牌、阶段标记) soup = BeautifulSoup(res_stage1.text, 'html.parser') csrf_token = soup.find('input', {'name': '_wpnonce'}).get('value') # 替换成实际的CSRF字段名 stage_param = {'stage': '2'} # 假设预览阶段的标识是stage=2 # 阶段2:预览表单(POST方法) payload_stage2 = {**payload_stage1, **stage_param, '_wpnonce': csrf_token} res_stage2 = session.post(url, data=payload_stage2) # 确认预览页面加载成功,比如检查是否有「下一步」按钮文本 if "下一步" not in res_stage2.text: print("预览阶段失败,响应内容:", res_stage2.text[:300]) exit() # 阶段3:广告升级选项(POST方法) # 这里要传递你选择的操作参数,比如点击「发送」按钮对应的name和value payload_stage3 = { 'action': 'send', # 替换成实际按钮的name属性值 'promotion': 'yes', # 如果选择升级广告,替换成实际选项值 '_wpnonce': csrf_token # 部分网站会复用令牌,也可能需要从预览页重新提取 } res_stage3 = session.post(url, data=payload_stage3) # 验证最终提交结果 if "提交成功" in res_stage3.text: print("多阶段表单提交完成!") else: print("提交失败,响应内容片段:", res_stage3.text[:500])
几个关键注意点
- 隐藏字段必须提取:不要凭空猜测参数,一定要从页面源码里找真实存在的字段(比如CSRF令牌,WordPress常用
_wpnonce) - 参数要完整传递:第二阶段的POST请求通常需要重新携带第一阶段的表单数据,否则网站无法识别你要预览的内容
- 每个阶段都要校验响应:避免在登录失败、第一阶段提交失败的情况下,继续执行后续步骤,浪费请求
内容的提问来源于stack exchange,提问作者Belloz
相关产品推荐
相关产品推荐

