Selenium Headless模式运行无输出 非Headless模式正常问题排查
Selenium Headless模式爬取日立配件站无数据输出问题修复
问题根因
- 反爬规则拦截:旧版Chrome无头模式(默认
--headless即--headless=old)存在明确的机器人特征:默认User-Agent携带HeadlessChrome标识、navigator.webdriver属性为true、缺少常规浏览器的字体、插件、WebGL指纹特征,日立配件站点的反爬策略识别到这类请求后会返回无数据的空白页面,因HTTP响应状态码仍为200,程序不会抛出请求类异常,解析空DOM结构自然得不到任何输出。 - 视口尺寸适配问题:未手动指定窗口参数时,Headless模式默认视口尺寸仅为800*600,站点响应式布局会将配件数据所在的列表模块折叠、设为延迟加载或移出可视区域,原有显式等待逻辑如果判定的是元素可见/可点击状态,会持续等待直到超时——如果代码中对等待超时异常做了静默捕获没有打印日志,就会出现“无报错、无输出”的现象。非Headless模式下浏览器默认窗口尺寸更大,数据模块正常渲染,等待条件可以正常触发。
- 渲染调度逻辑差异:Headless模式下Chrome的资源调度优先级和有头模式不同,部分拉取配件数据的动态JS接口会被延后执行,如果代码以
DOMContentLoaded作为页面加载完成的判定节点,会在核心数据还没返回时就启动解析,拿到的自然是空内容。
修复方案
- 替换无头模式参数,补全反爬绕过配置
Chrome 112及以上版本已经推出和真实浏览器行为完全一致的新版无头模式,初始化浏览器时替换原有裸--headless参数,同时补全必要配置:from selenium.webdriver import ChromeOptions, Chrome import tempfile options = ChromeOptions() # 启用新版无头模式,渲染行为、指纹特征和有头模式完全对齐 options.add_argument("--headless=new") # 固定和有头模式一致的窗口尺寸,避免响应式布局异常 options.add_argument("--window-size=1920,1080") # 禁用Blink自动化特征标识 options.add_argument("--disable-blink-features=AutomationControlled") # 覆盖默认UA,移除Headless标识 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") # 并发场景必要参数:关闭沙箱、禁用共享内存分区、给每个实例分配独立临时目录 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument(f"--user-data-dir={tempfile.mkdtemp()}") # 关闭不必要的功能,减少无头模式运行异常 options.add_argument("--disable-extensions") options.add_argument("--disable-gpu") driver = Chrome(options=options) # 启动后覆盖navigator.webdriver属性,绕过基础检测 driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})" }) - 调整页面等待逻辑
移除无日志的异常捕获,不要用固定时长的time.sleep()或者页面load事件作为解析触发条件,直接等待配件数据的核心容器元素加载完成再解析:from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 超时时间设为15秒,超时会直接抛出异常打印日志,方便排查 wait = WebDriverWait(driver, 15) # 替换为实际配件列表的CSS选择器/XPATH data_container = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "配件数据容器的选择器"))) - 并发数控制
无头模式下Chrome内存占用比有头模式低30%左右,但单台机器的并发实例数不要超过CPU核心数的2倍,避免资源不足导致页面渲染失败。 - 快速调试方法
排查阶段可以在页面加载完成后加一行截图代码driver.save_screenshot("debug_screenshot.png"):如果截图显示空白页/人机验证页,说明仍被反爬拦截;如果截图布局错乱,检查窗口尺寸和等待逻辑。
内容的提问来源于stack exchange,提问作者Martin H
相关产品推荐
相关产品推荐

