Selenium无法获取JS生成的Cloudflare验证元素,如何点击通过?
问题描述
使用Selenium访问带有Cloudflare机器人检测与DDoS防护的网站时,页面加载后出现人机验证元素:白色框为名为mark的span标签,隐藏蓝色框为type='checkbox'的input标签。尝试了常规定位方法(driver.find_elements(By.CLASS_NAME, "class")、XPath、CSS选择器、JsPath)及driver.execute_script执行JS查询的方式,均无法找到元素(已排除等待问题)。
尝试的代码如下:
markSpanJsPath = driver.execute_script("return document.querySelector('#cf-stage > div.ctp-checkbox-container > label > span')") if markSpanJsPath:#kkk print('found markSpanJsPath') driver.execute_script("arguments[0].click();", markSpanJsPath) print('found markSpanJsPath js click') markSpanXpath = driver.find_elements(By.XPATH,'//*[@id="cf-stage"]/div[6]/label/span') if markSpanXpath: print('found markSpanXpath') driver.execute_script("arguments[0].click();", markSpanXpath) print('found markSpanXpath js click')
代码运行后无任何输出,需解决如何点击mark span或checkbox元素以通过人机验证的问题。
解决方案
1. 检查验证元素是否在iframe中
Cloudflare的人机验证模块通常嵌入在独立iframe内,常规DOM查询无法直接定位到iframe内的元素,需先切换iframe:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待验证iframe加载并切换 WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it( (By.CSS_SELECTOR, "iframe[title='Widget containing a Cloudflare security challenge']") )) # 切换后定位元素并点击 checkbox = driver.find_element(By.CSS_SELECTOR, ".ctp-checkbox-container input[type='checkbox']") driver.execute_script("arguments[0].click();", checkbox) # 操作完成切回主文档 driver.switch_to.default_content()
2. 规避Cloudflare的Selenium检测
Selenium默认特征易被识别为机器人,需修改浏览器启动参数隐藏自动化标识:
from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() # 禁用自动化检测特征 options.add_argument("--disable-blink-features=AutomationControlled") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) # 添加真实用户代理 options.add_argument("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") # 禁用沙箱和扩展 options.add_argument("--no-sandbox") options.add_argument("--disable-extensions") driver = webdriver.Chrome(options=options) # 进一步清除navigator.webdriver标识 driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
3. 使用稳定的元素选择器
避免依赖动态索引的XPath(如div[6]),改用基于class或属性的选择器:
- 定位mark span:
By.CSS_SELECTOR, ".ctp-checkbox-container span.mark" - 定位checkbox:
By.CSS_SELECTOR, ".ctp-checkbox-container input[type='checkbox']"
4. 模拟真实鼠标点击
若JS点击无效,尝试用ActionChains模拟真实交互:
from selenium.webdriver.common.action_chains import ActionChains # 定位元素后执行点击 action = ActionChains(driver) action.move_to_element(checkbox).click().perform()
内容的提问来源于stack exchange,提问作者Farhang Amaji
相关产品推荐
相关产品推荐

