如何通过Python脚本修改Magento账户密码,现有代码不生效如何解决?
调整方案及修正代码
核心问题原因
- 复用了登录页获取的
form_key:Magento的form_key是单次会话单页生效的,登录成功后跳转至账户相关页面时,旧的form_key会被服务端作废,改密码请求需要用改密码页面全新生成的form_key - 缺少登录状态校验:未验证登录请求是否真的成功,可能登录被拦截(比如触发人机验证、账号密码错误)的情况下直接发起改密码请求,自然失败
- 缺少必要的请求头参数:Magento服务端会校验请求的
User-Agent、Referer等头字段,缺失的话会被判定为非法请求直接拒绝 - 可能存在遗漏的表单参数:部分Magento版本的改密码表单会有额外隐藏字段,只传手动列的4个参数会不符合校验规则
具体调整步骤
- 登录成功后,先请求改密码页面,从该页面重新提取
form_key以及所有隐藏表单字段 - 每次请求都携带符合浏览器特征的
User-Agent,以及对应页面的Referer头 - 新增登录成功校验逻辑,确认登录有效后再执行改密码操作
- 提交改密码请求时,使用从改密码页提取的全新
form_key和所有表单参数
修正后代码示例
import requests from bs4 import BeautifulSoup # 配置参数 web_user = "你的账号邮箱" web_pass = "原密码" new_pass = "新密码" # 配置请求头,模拟普通浏览器 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", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" } s = requests.session() s.headers.update(headers) # 第一步:获取登录页form_key main_url = 'https://account.magento.com/customer/account/login/' html_data = s.get(main_url) form_soup = BeautifulSoup(html_data.content, 'html.parser') form_key = form_soup.find('input', {'name':'form_key'})['value'] # 第二步:提交登录请求,携带Referer login_route = 'https://account.magento.com/customer/account/loginPost/' login_payload = { 'form_key': form_key, 'login[username]': web_user, 'login[password]': web_pass } login_req = s.post(login_route, data=login_payload, headers={"Referer": main_url}) # 校验是否登录成功:检查响应中是否存在登出链接(或其他账户页特有元素) if "customer/account/logout" not in login_req.text: raise Exception("登录失败,请检查账号密码或是否触发人机验证") # 第三步:请求改密码页面,提取新的form_key change_pwd_page = "https://account.magento.com/customer/account/changepassword/" pwd_page_data = s.get(change_pwd_page, headers={"Referer": "https://account.magento.com/customer/account/"}) pwd_soup = BeautifulSoup(pwd_page_data.content, 'html.parser') # 提取改密码页的全新form_key new_form_key = pwd_soup.find('input', {'name':'form_key'})['value'] # 第四步:提交改密码请求,使用新的form_key account_change_password_post = "https://account.magento.com/customer/account/changePasswordPost/" change_password_payload = { 'form_key': new_form_key, 'current_password': web_pass, 'password': new_pass, 'password_confirmation' : new_pass } # 可选:提取改密码表单所有隐藏字段,避免参数遗漏 for hidden_input in pwd_soup.select("#form-validate input[type='hidden']"): change_password_payload[hidden_input['name']] = hidden_input['value'] change_pass_req = s.post(account_change_password_post, data=change_password_payload, headers={"Referer": change_pwd_page}) # 校验改密码结果 if "password was successfully changed" in change_pass_req.text: print("密码修改成功") else: print("密码修改失败,响应信息:", change_pass_req.text[:500])
额外注意事项
- 如果账号开启了二步验证,需要额外添加二步验证的验证码提交逻辑
- 若请求被拦截返回403/人机验证页面,需要添加代理、Cookie池或者CAPTCHA识别逻辑适配反爬规则
内容的提问来源于stack exchange,提问作者Mercer
相关产品推荐
相关产品推荐

