如何用Python requests/MechanicalSoup+2Captcha解决eBay.de HCaptcha及CSRF报错
eBay.de站点HCaptcha验证CSRF报错解决方案
问题描述
通过Python的MechanicalSoup库结合2Captcha API完成eBay.de站点HCaptcha验证时,2Captcha服务及API密钥运行正常,但向eBay提交验证请求时返回b'CSRF_VALIDATION_ERR'错误,经确认问题出在eBay侧校验逻辑。
现有实现代码
from twocaptcha import TwoCaptcha import mechanicalsoup import sys import os sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"] browser = mechanicalsoup.StatefulBrowser() browser.set_user_agent(user_agents[0]) url = 'https://www.ebay.de/bin/purchaseHistory?item=233592905862&rt=nc&_trksid=p2047675.l2564' res = browser.open(url) form = res.soup.find('form', {'id': 'captcha_form'}) srt = form.find('input', {'name': 'srt'})['value'] ru = form.find('input', {'name': 'ru'})['value'] cptap = form.find('input', {'name': 'cptap'})['value'] appName = form.find('input', {'name': 'appName'})['value'] cptrdbpid = form.find('input', {'name': 'cptrdbpid'})['value'] iia = form.find('input', {'name': 'iia'})['value'] iiz = form.find('input', {'name': 'iiz'})['value'] iim = form.find('input', {'name': 'iim'})['value'] # browser.launch_browser() api_key = os.getenv('APIKEY_2CAPTCHA', 'ad0d381411ecaf40977c8a18f719321e') solver = TwoCaptcha(api_key) try: result = solver.hcaptcha( sitekey=cptrdbpid, url=url, ) except Exception as e: print('Not solved') else: print('solved: ' + str(result)) payload = {"srt": srt, "ru": ru, "cptap": cptap, "appName": appName, "cptrdbpid": cptrdbpid, "iia": iia, "iiz": iiz, "iim": iim, "g-recaptcha-response": result['code'], "h-captcha-response": result['code'], "captchaTokenInput": "%7B%22guid%22%3A%" + cptrdbpid + '22%22%2C%22provider%22%3A%22hcaptcha%22%2C%22appName%22%3A%22orch%22%2C%22token%22%3A%22' + result['code'] + "%22%7D" } headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "accept-encoding": "gzip, deflate, br", "accept-language": "de-DE,de;q=0.9", "cache-control": "max-age=0", "content-type": "application/x-www-form-urlencoded", "origin": "https://www.ebay.de", "referer": browser.url, "sec-ch-ua": '"Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "Windows", "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "same-origin", "sec-fetch-user": "?1", "upgrade-insecure-requests": "1"} res = browser.post('https://www.ebay.de/splashui/captcha_submit', json=payload, allow_redirects=True, timeout=15, headers=headers)
修复步骤
- 修正提交数据格式冲突:你在请求头中指定了
content-type: application/x-www-form-urlencoded,但调用post方法时使用了json=payload参数,该参数会自动覆盖Content-Type为application/json,导致eBay无法解析表单数据触发CSRF校验失败,将json=payload改为data=payload即可。 - 修复captchaTokenInput编码错误:手动拼接URL编码串存在语法缺失,
%7B%22guid%22%3A%后少了编码字符22,建议通过urllib自动生成编码内容避免手写错误,示例代码如下:
import json import urllib.parse captcha_info = { "guid": cptrdbpid, "provider": "hcaptcha", "appName": "orch", "token": result['code'] } payload["captchaTokenInput"] = urllib.parse.quote_plus(json.dumps(captcha_info))
- 避免遗漏隐藏表单字段:手动逐个提取表单input容易漏取eBay动态生成的CSRF校验字段,建议遍历整个表单自动收集所有参数:
payload = {} for input_item in form.find_all('input', {'name': True}): payload[input_item['name']] = input_item.get('value', '') # 后续再追加h-captcha-response等验证字段即可
- 统一UA版本:你初始化浏览器时使用的UA是Chrome 91版本,但请求头
sec-ch-ua中写的是Chrome 95版本,UA信息不一致会触发eBay反爬校验,将两处版本号改为一致即可。
内容的提问来源于stack exchange,提问作者Oliver W
相关产品推荐
相关产品推荐

