无法提取房源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函数里有两个潜在问题:
- 直接用
driver.get(listing_url)会离开当前列表页,来回切换容易触发反爬,也可能导致会话不稳定 - 依赖层级的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])
三、调整超时时间与反爬规避
- 全局的
TIMEOUT = 5设置太短,尤其是网络波动或者页面加载慢的时候,建议改成10秒 - 每次爬完一页后加随机延迟,避免请求过于频繁触发反爬拦截:
# 在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
相关产品推荐
相关产品推荐

