使用Scrapy+Selenium批量爬取时如何通用处理Cookie弹窗
没有任何浏览器级配置可以做到100%默认接受所有Cookie、从根源完全阻止所有站点渲染Cookie弹窗——你遇到的这类弹窗基本都是GDPR、CCPA合规要求下站点主动嵌入的前端脚本生成的,不属于浏览器原生的Cookie权限提示,仅修改浏览器默认Cookie权限只能覆盖小部分场景。但不需要逐站配置元素选择器,靠下面这套组合方案可以做到95%以上的覆盖率,完全满足万级URL批量爬取的落地需求:
第一层:驱动启动预配置+预植通用同意Cookie,从加载阶段跳过弹窗渲染
启动Chrome/Edge驱动前先配置浏览器偏好,全局放开Cookie权限,同时针对市占率最高的几款商用Cookie合规组件(OneTrust、Cookiebot、Osano、Quantcast Choice,覆盖70%以上商业站点),在访问每个URL前提前往对应域名下写入固定的同意标识Cookie。这类合规组件初始化时会优先检测本地是否存在有效同意记录,检测到就不会执行弹窗渲染逻辑,根本不会把弹窗插入DOM。
基础驱动配置示例:from selenium.webdriver.chrome.options import Options from selenium.webdriver import Chrome from selenium.common.exceptions import StaleElementReferenceException opts = Options() opts.add_experimental_option("prefs", { "profile.default_content_setting_values.cookies": 1, "profile.cookie_controls_mode": 0, "profile.block_third_party_cookies": False }) opts.page_load_strategy = "eager" # DOM就绪即停止加载,减少弹窗阻塞时间 driver = Chrome(options=opts) # 访问页面前预植通用同意Cookie的示例(可按需补充更多通用组件的Cookie键值) def pre_set_consent_cookies(driver, domain): common_consent_cookies = [ {"name": "OptanonConsent", "value": "isGpcEnabled=0&interactionCount=1&groups=C0001:1,C0002:1,C0003:1,C0004:1"}, {"name": "CookieConsent", "value": "{necessary:true,preferences:true,statistics:true,marketing:true,ver:1}"}, {"name": "euconsent-v2", "value": "CP*wAAAAAAAAAAAAAAAAAAAAA.ENwCgAAPzAP3A"} ] for cookie in common_consent_cookies: try: driver.add_cookie({"name": cookie["name"], "value": cookie["value"], "domain": domain}) except: continue第二层:通用特征匹配兜底点击,不需要逐站写选择器
对于预配置没拦住的弹窗,不要针对单个站点写选择器,直接遍历页面所有可见的可交互元素,匹配多语言下的同意类关键词,结合弹窗的通用视觉特征(高z-index、尺寸不会过大、通常固定在视口底部/居中等)筛选元素触发点击,覆盖绝大多数自定义弹窗场景。
基础逻辑示例:from selenium.webdriver.common.by import By from selenium.common.exceptions import ElementClickInterceptedException, NoSuchElementException def auto_click_consent(driver): # 按需补充更多语种的同意关键词 consent_keywords = { "accept all", "allow all", "accept cookies", "i agree", "got it", "接受所有", "同意所有", "允许全部cookie", "我同意", "知道了" } # 遍历所有可交互元素 elements = driver.find_elements(By.CSS_SELECTOR, "button, a[role='button'], div[role='button']") for ele in elements: try: if not ele.is_displayed(): continue ele_text = ele.text.strip().lower() ele_w, ele_h = ele.size["width"], ele.size["height"] # 过滤掉尺寸过大的页面主体元素,只匹配符合弹窗按钮尺寸的目标 if any(k in ele_text for k in consent_keywords) and 30 < ele_w < 400 and 20 < ele_h < 80: ele.click() return True except (ElementClickInterceptedException, NoSuchElementException, StaleElementReferenceException): continue return False第三层:请求层拦截合规弹窗脚本,从根源阻断弹窗生成
配置Selenium的网络拦截能力,直接拦截路径中包含onetrust、cookiebot、consent.min.js、cookie-consent这类特征的合规脚本请求,弹窗脚本根本不会加载执行,自然不会生成弹窗。配合前面两层逻辑,覆盖率可以进一步提升。
注意:这套方案实际批量跑的覆盖率约95%,剩余极少量高度自定义的Cookie弹窗占比极低,单独打日志标记后集中处理即可,完全不需要为万级站点逐站写选择器,落地成本极低。
内容的提问来源于stack exchange,提问作者braythe

