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

使用Selenium+JavaScript拦截Ahrefs的Turnstile验证码参数失败,寻求对接2Captcha的解决办法

使用Selenium+JavaScript拦截Ahrefs的Turnstile验证码参数失败,寻求对接2Captcha的解决办法

嘿,我之前也踩过类似的坑,Ahrefs的Cloudflare Turnstile确实有点磨人,尤其是参数拦截这块。结合我折腾出来的经验,给你几个针对性的解决思路:

1. 先搞定浏览器指纹,别让Cloudflare认出你是自动化工具

你用的是headless模式,Chrome默认的headless UA会带Headless标识,一眼就被Cloudflare识破了。用seleniumbase的话,一定要开undetectable模式,再补全一些指纹参数:

driver = Driver(
    browser="chrome",
    headless=True,
    proxy=proxy,
    agent=agent,
    undetectable=True,  # 核心!这个模式会帮你隐藏自动化痕迹
    extra_capabilities={
        "goog:chromeOptions": {
            "excludeSwitches": ["enable-automation"],
            "useAutomationExtension": False,
            "args": [
                "--disable-blink-features=AutomationControlled",
                "--window-size=1920,1080",  # 模拟真实窗口大小
                "--disable-dev-shm-usage"
            ]
        }
    }
)

2. 换个方式拿Turnstile参数,别死磕JavaScript拦截

Ahrefs的Turnstile参数(sitekey、action)不一定需要用JS拦截,直接解析页面更靠谱:

方法一:从Turnstile元素提取属性

用WebDriverWait等元素加载完成后,直接拿data-sitekey和data-action:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 15)
# 等待Turnstile容器加载
turnstile_container = wait.until(
    EC.presence_of_element_located((By.CSS_SELECTOR, 'div[data-sitekey]'))
)
sitekey = turnstile_container.get_attribute('data-sitekey')
action = turnstile_container.get_attribute('data-action')  # 部分站点需要这个参数

方法二:正则匹配页面源码

如果元素加载慢或者被动态渲染,直接扒页面源码用正则抓:

page_source = driver.page_source
sitekey_match = re.search(r'data-sitekey="([a-zA-Z0-9_-]+)"', page_source)
if sitekey_match:
    sitekey = sitekey_match.group(1)
else:
    raise Exception("没找到sitekey,检查页面加载状态")

3. 对接2Captcha的正确姿势

拿到sitekey和当前页面URL后,按照2Captcha的API规范提交任务:

import requests

def solve_turnstile(sitekey, page_url, api_key, proxy=None, action=None):
    # 组装请求参数
    payload = {
        'key': api_key,
        'method': 'turnstile',
        'sitekey': sitekey,
        'pageurl': page_url,
        'json': 1
    }
    # 可选参数:action和代理
    if action:
        payload['action'] = action
    if proxy:
        # 转换为2Captcha要求的代理格式:login:password@ip:port
        proxy_str = proxy.replace('@', ':').split('://')[-1]
        payload['proxy'] = proxy_str
        payload['proxytype'] = 'HTTP'

    # 提交任务
    submit_res = requests.post('https://2captcha.com/in.php', data=payload).json()
    if submit_res['status'] != 1:
        raise Exception(f"提交任务失败:{submit_res['request']}")
    
    task_id = submit_res['request']
    # 轮询等待结果
    time.sleep(10)
    while True:
        result_res = requests.get(
            f'https://2captcha.com/res.php?key={api_key}&action=get&id={task_id}&json=1'
        ).json()
        if result_res['status'] == 1:
            return result_res['request']  # 返回验证token
        elif result_res['request'] == 'CAPCHA_NOT_READY':
            time.sleep(5)
        else:
            raise Exception(f"验证码解析失败:{result_res['request']}")

# 调用示例
current_url = driver.current_url
turnstile_token = solve_turnstile(sitekey, current_url, my_key, proxy, action)

4. 把token注入页面,完成验证

拿到token后,要把它填入Turnstile对应的隐藏输入框,必要时触发事件:

# 注入token到页面
driver.execute_script(f'''
    const responseInput = document.querySelector('input[name="cf-turnstile-response"]');
    if (responseInput) {{
        responseInput.value = "{turnstile_token}";
        // 触发验证完成的事件,有些站点需要这个
        responseInput.dispatchEvent(new Event('input'));
        responseInput.dispatchEvent(new Event('change'));
    }}
''')

最后提几个注意事项

  • 不要频繁请求Ahrefs,很容易触发反爬,加合理的等待时间
  • 代理一定要稳定,避免因为代理IP问题导致页面加载异常或者被拦截
  • 如果还是拿不到参数,试试关闭headless模式先手动看看页面结构,确认sitekey的位置

备注:内容来源于stack exchange,提问作者divinem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 09:49:38