如何用Selenium处理Cloudflare Turnstile?现有方案遭拦截求解决
解决Selenium被Cloudflare拦截的方案
问题描述
我尝试用Selenium访问某网站失败,试过undetected_chromedriver、添加用户配置文件、使用代理这些方法,但WebDriver打开网站时会被Cloudflare拦截,正常Chrome浏览器却能正常访问,求解决办法。
附测试代码:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from datetime import datetime import time from undetected_chromedriver import Chrome from selenium.webdriver.common.by import By # 原代码缺失该导入,已补充 now = datetime.now() current_time = now.strftime("%H:%M:%S") print('Hey Elior, im on = ', current_time) options = webdriver.ChromeOptions() options.add_argument("user-data-dir=C:\\Users\\Owner\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 12") driver = Chrome(chrome_options=options) driver.get("https://www.example.com") def login(): driver.get("site") # identify username, password and signin elements time.sleep(1) driver.find_element(By.NAME, "username").click() driver.find_element(By.NAME, "username").send_keys('') time.sleep(1) driver.find_element(By.NAME, "password").click() driver.find_element(By.NAME, "password").send_keys('') time.sleep(1) # press on login button driver.find_element(By.ID, "login-submit").click() driver.maximize_window() driver.execute_script("console.clear()") # clean the console time.sleep(3)
可行解决方案
1. 强化undetected_chromedriver的反检测配置
默认配置的伪装程度不足,补充以下参数模拟真实浏览器:
- 移除自动化标识,避免被Cloudflare识别为爬虫
- 复制正常Chrome的User-Agent,替换默认的自动化代理
- 确保JS和图片正常加载,不要禁用核心功能
修改后的初始化代码:
options = webdriver.ChromeOptions() # 加载已验证过的用户配置文件 options.add_argument("user-data-dir=C:\\Users\\Owner\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 12") # 移除自动化标识 options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) # 替换为你真实Chrome的User-Agent(可在浏览器控制台输入navigator.userAgent获取) options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36") # 启用JS和图片加载 options.add_argument("--enable-javascript") options.add_argument("--disable-images=false") driver = Chrome(options=options) # 执行脚本隐藏webdriver属性 driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
2. 优化用户配置文件的使用逻辑
确保你用的Chrome配置文件是已手动通过Cloudflare验证、且正常登录过目标网站的:
- 关闭所有Chrome进程,避免配置文件被占用
- 手动用该配置文件打开Chrome,访问目标网站确认能正常进入,再启动Selenium加载该配置
3. 替换固定等待为显式等待
原代码的time.sleep()过于生硬,改用Selenium显式等待,贴合真实用户操作节奏:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def login(): driver.get("site") # 等待用户名输入框出现并可操作 username_input = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.NAME, "username")) ) username_input.send_keys('你的用户名') # 等待密码输入框出现并可操作 password_input = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.NAME, "password")) ) password_input.send_keys('你的密码') # 等待登录按钮可点击 login_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "login-submit")) ) login_btn.click() driver.maximize_window() driver.execute_script("console.clear()") # 等待登录成功页面加载完成 WebDriverWait(driver, 5).until(EC.title_contains("登录成功")) # 根据网站实际标题调整
4. 用CDP命令增强浏览器伪装
通过Chrome DevTools协议修改浏览器核心属性,进一步隐藏自动化痕迹:
# 初始化driver后执行以下命令 driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', { 'source': ''' // 隐藏webdriver标识 Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); // 模拟真实插件数量 Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4]}); // 设置真实语言 Object.defineProperty(navigator, 'languages', {get: () => ['zh-CN', 'zh']}); ''' })
5. 尝试用Playwright替代Selenium
Playwright自带更强的反检测机制,对Cloudflare兼容性更好,代码示例:
from playwright.sync_api import sync_playwright with sync_playwright() as p: # 加载已验证的用户配置文件 browser = p.chromium.launch_persistent_context( user_data_dir="C:\\Users\\Owner\\AppData\\Local\\Google\\Chrome\\User Data\\Profile 12", headless=False, args=["--disable-blink-features=AutomationControlled"] ) page = browser.new_page() page.goto("site") # 执行登录操作 page.fill('[name="username"]', '你的用户名') page.fill('[name="password"]', '你的密码') page.click('#login-submit') # 等待页面加载完成 page.wait_for_load_state('networkidle') # 后续操作逻辑 browser.close()
内容的提问来源于stack exchange,提问作者Elior
相关产品推荐
相关产品推荐

