You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法提取房源EPC评级且脚本频繁超时的问题排查求助

无法提取房源EPC评级且脚本频繁超时的问题排查求助

嘿,我看了你爬取Zoopla房源EPC评级的脚本,频繁超时确实挺闹心的,咱们从几个常见的方向来排查和解决问题:

一、先排查无头浏览器的配置问题

你提到怀疑无头浏览器加载异常,这点很有道理。undetected-chromedriver默认可能不是无头模式,就算开启了旧版无头,也容易被网站检测到,或者渲染不完整。建议你手动配置新版无头模式,同时加上模拟真实浏览器的参数:

from selenium.webdriver.chrome.options import ChromeOptions

# 在main函数前添加配置
options = ChromeOptions()
# 新版无头模式,行为更接近真实Chrome
options.add_argument("--headless=new")
# 设置窗口大小,避免无头模式下布局异常
options.add_argument("--window-size=1920,1080")
# 禁用自动化特征检测,降低被反爬识别的概率
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--disable-gpu")

# 初始化driver时传入配置
with Chrome(options=options) as driver:

二、优化页面跳转后的等待逻辑

你的get_epc_rating函数里有两个潜在问题:

  1. 直接用driver.get(listing_url)会离开当前列表页,来回切换容易触发反爬,也可能导致会话不稳定
  2. 依赖层级的CSS选择器太脆弱,页面结构稍有变化就会失效,而且超时时间只有5秒,可能不够

推荐改成新标签页打开房源,同时用更稳定的元素定位方式:

import time
import random

def get_epc_rating(driver: WebDriver, listing_url: str) -> str:
    # 用JS打开新标签页,避免离开列表页
    driver.execute_script("window.open(arguments[0]);", listing_url)
    driver.switch_to.window(driver.window_handles[-1])
    
    try:
        # 先等待页面主内容加载完成
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.main-content')))
        
        # 用XPATH定位包含"EPC rating"的标签,再找相邻的评级元素(更稳定)
        epc_label = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, "//div[contains(normalize-space(text()), 'EPC rating')]"))
        )
        epc_element = epc_label.find_element(By.XPATH, "./following-sibling::div")
        
        # 加随机延迟,模拟人类操作
        time.sleep(random.uniform(1, 2))
        return etext(epc_element)
    
    except TimeoutException:
        return "N/A"
    
    finally:
        # 关闭当前标签页,切回列表页
        driver.close()
        driver.switch_to.window(driver.window_handles[0])

三、调整超时时间与反爬规避

  1. 全局的TIMEOUT = 5设置太短,尤其是网络波动或者页面加载慢的时候,建议改成10秒
  2. 每次爬完一页后加随机延迟,避免请求过于频繁触发反爬拦截:
# 在scrape_page之后、click_next之前加延迟
all_results.extend(scrape_page(driver))
time.sleep(random.uniform(2, 4))  # 模拟人类翻页间隔
click_next(driver)

四、优化Cookie弹窗处理

有时候usercentrics的shadow root加载会有延迟,你可以给它加个显式等待,确保能正确找到拒绝按钮:

def click_through(driver: WebDriver) -> None:
    try:
        wait = WebDriverWait(driver, TIMEOUT)
        # 先等待Cookie容器加载完成
        shadow_container = wait.until(EC.presence_of_element_located((By.ID, "usercentrics-root")))
        shadow_root = shadow_container.shadow_root
        # 等待拒绝按钮可点击
        button = wait.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "button[data-testid=uc-deny-all-button]")
        ))
        click(driver, button)
        time.sleep(1)  # 给页面一点时间处理Cookie状态
    except Exception:
        pass

五、检查CSS选择器的稳定性

你在scrape_page里用的很多CSS选择器都是依赖层级的(比如div:nth-child(2)),建议尽量找带有data-testid的元素,或者语义化的类名,避免页面结构变化导致元素定位失败。

可以先手动打开Zoopla的房源页,用浏览器开发者工具检查EPC评级元素的真实定位,确认选择器是否正确。


备注:内容来源于stack exchange,提问作者Chioma Okoroafor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:09:50