Selenium无头Chrome模拟普通PC请求 解决NoSuchElementException报错
Selenium无头Chrome反识别解决方案
问题原因
网站通过浏览器指纹特征识别到当前访问为Selenium无头模式,因此返回了和普通访问不同的阉割版页面,导致目标元素不存在。
解决方案
1. 优先使用新版无头模式(Chrome 112及以上版本)
老版--headless启动参数的特征和普通Chrome差异极大,Chrome 112后推出的新版无头模式和普通浏览模式几乎完全一致,直接替换启动参数即可:
from selenium import webdriver options = webdriver.ChromeOptions() # 替换原有旧无头模式参数 options.add_argument("--headless=new")
2. 配置反识别启动参数
添加以下参数抹平无头模式和普通Chrome的特征差异:
# User-Agent替换为本地普通Chrome的UA,可在普通Chrome地址栏输入chrome://version/ 查看复制 options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") # 移除自动控制标记 options.add_argument("--disable-blink-features=AutomationControlled") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option("useAutomationExtension", False) # 启动即最大化,避免默认小窗口触发反爬规则 options.add_argument("--start-maximized") # 适配无头模式运行环境,避免权限、内存相关问题 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage")
3. 注入JS覆盖浏览器指纹特征
启动driver后注入JS代码,修改Selenium特有的暴露属性:
driver = webdriver.Chrome(options=options) driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ // 隐藏webdriver标记 Object.defineProperty(navigator, 'webdriver', {get: () => undefined}) // 模拟正常Chrome的插件、语言属性 window.navigator.chrome = {runtime: {}} Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5]}) Object.defineProperty(navigator, 'languages', {get: () => ['zh-CN', 'zh', 'en']}) """ })
4. 添加强制等待逻辑
部分动态渲染的元素需要等待加载完成后再操作,推荐使用显式等待替代直接查找元素,避免提前查找触发元素不存在报错:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 最长等待10秒,直到目标元素出现后执行点击 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, 'mat-option-17')) ).click()
完成以上配置后,无头Chrome的特征将和普通Chrome高度一致,网站无法识别访问差异,返回的页面内容会完全同步。
内容的提问来源于stack exchange,提问作者Derik002
相关产品推荐
相关产品推荐

