You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

基于Python Requests实现WordPress密码重置自动化及问题排查方案

WordPress 密码重置自动化与性能测试方案

我明白你在测试WordPress密码重置流程性能时遇到的痛点——Selenium这类浏览器工具确实太笨重,没法高效模拟大量并发请求。针对你的三个问题,我逐一解答,重点放在第三个核心需求上:


问题1:为什么仅发送单个POST请求无法完成新密码提交(即使包含pass1和pass2)?

WordPress的密码重置页面依赖会话上下文CSRF验证机制

  • 首先,你需要先通过GET请求访问重置链接,服务器会给你的会话设置Cookie,同时页面里会生成唯一的_wpnonce(CSRF令牌)和rp_key等隐藏字段。
  • 直接发送POST请求时,既没有带上会话Cookie,也没有包含这些验证字段,服务器会判定这是非法请求,直接拒绝处理。这就是单独POST无法成功的核心原因。

问题2:为什么浏览器里只显示一个密码输入字段,但GET请求/Postman里看到两个?

这是WordPress的前端用户体验优化:

  • 在浏览器中,WordPress会用JavaScript隐藏pass2字段,只展示pass1,并实时同步两个字段的值(避免用户重复输入)。
  • 但后端为了兼容无JS的场景,仍然要求pass1pass2两个字段都有值且一致。所以在非浏览器工具中,必须同时传入这两个字段。

问题3:如何通过Requests或其他非浏览器工具实现WordPress密码重置的自动化(支持并行测试)?

这是最关键的部分,我给你一套完整的Python实现方案,用requests处理HTTP请求,BeautifulSoup解析页面提取必要参数,再用多线程模拟并发请求:

前置准备

先安装依赖包:

pip install requests beautifulsoup4

完整代码实现

import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor

# 自定义配置
WP_BASE_URL = "http://localhost/wordpress_5_4_2_try3/wp-login.php"
NEW_PASSWORD = "a_password#38"

def reset_single_user(username, reset_key):
    # 用Session保持会话Cookie
    session = requests.Session()
    try:
        # 第一步:访问重置页面,提取验证字段
        reset_url = f"{WP_BASE_URL}?action=rp&key={reset_key}&login={username}"
        get_response = session.get(reset_url)
        get_response.raise_for_status()  # 捕获HTTP错误

        # 解析页面,提取表单所有字段(包括隐藏字段)
        soup = BeautifulSoup(get_response.text, "html.parser")
        reset_form = soup.find("form", id="resetpassform")
        if not reset_form:
            print(f"❌ 用户 {username}:未找到重置表单")
            return False

        form_data = {}
        for input_tag in reset_form.find_all("input"):
            name = input_tag.get("name")
            value = input_tag.get("value", "")
            if name:
                form_data[name] = value

        # 设置新密码(必须同时传pass1和pass2)
        form_data["pass1"] = NEW_PASSWORD
        form_data["pass2"] = NEW_PASSWORD

        # 第二步:提交密码重置请求
        post_response = session.post(reset_url, data=form_data)
        post_response.raise_for_status()

        # 验证重置是否成功(根据页面内容判断,可自定义)
        success_indicators = ["密码已重置", "您的密码已更新", "Log In"]
        if any(indicator in post_response.text for indicator in success_indicators):
            print(f"✅ 用户 {username}:密码重置成功")
            return True
        else:
            print(f"❌ 用户 {username}:重置失败,页面返回:{post_response.text[:300]}...")
            return False

    except Exception as e:
        print(f"⚠️ 用户 {username}:处理出错 - {str(e)}")
        return False

# 模拟批量测试用户(这里可以从你的存储文件中读取真实的用户和重置key)
test_users = [
    {"username": "user_test_1", "reset_key": "your_reset_key_1"},
    {"username": "user_test_2", "reset_key": "your_reset_key_2"},
    # 可以添加更多用户...
]

# 并发执行:max_workers根据服务器性能调整,别太激进
if __name__ == "__main__":
    with ThreadPoolExecutor(max_workers=10) as executor:
        # 提交所有重置任务
        futures = [
            executor.submit(reset_single_user, user["username"], user["reset_key"])
            for user in test_users
        ]
        # 等待所有任务完成
        for future in futures:
            future.result()

核心要点说明

  1. 会话保持:用requests.Session()自动管理Cookie,确保请求在同一个会话中
  2. 字段提取:通过解析页面获取_wpnoncerp_key等验证字段,避免硬编码
  3. 并发处理:用ThreadPoolExecutor实现多线程并发,模拟大量用户同时操作
  4. 错误处理:加入HTTP状态码检查和异常捕获,方便排查问题
  5. 成功验证:通过页面中的关键词判断重置是否成功,可根据你的WordPress语言版本调整

如果需要更高性能的并发测试,也可以用Go语言编写(原生协程性能更好),但上述Python方案已经足够应对大多数场景,而且代码更易维护。


内容的提问来源于stack exchange,提问作者Eva Anastasiadi

火山引擎 最新活动