You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:14:53