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

使用Python3的Selenium爬取JS渲染页面仅获脚本的问题排查

解决Selenium提取Google Flights动态DOM元素的问题

我之前也碰到过类似的情况,Google Flights这类重度依赖JavaScript动态渲染的页面,光靠implicitly_wait往往不够——它只是设置了元素查找的全局超时,没法精准等待页面核心内容的渲染完成。下面是几个关键调整点,帮你拿到完整的DOM内容:

1. 改用显式等待,精准等待核心元素加载

隐式等待的局限性在于,它只保证元素能被找到,但Google Flights的航班数据是通过AJAX异步加载后再渲染到页面上的,这时候页面的readyState可能已经是complete,但实际内容还没出来。我们可以用WebDriverWait等待特定的DOM元素出现,比如航班卡片:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

url = 'https://www.google.com/flights/explore/#explore;f=BDO;t=r-Asia-0x88d9b427c383bc81%253A0xb947211a2643e5ac;li=0;lx=2;d=2018-01-09'

# 配置Chrome选项,最大化窗口确保渲染完整
options = webdriver.ChromeOptions()
options.add_argument('--start-maximized')
# 可选:设置模拟人类的User-Agent,降低被反爬检测的概率
options.add_argument('--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"')

driver = webdriver.Chrome(executable_path="/var/chromedriver/chromedriver", options=options)

try:
    driver.get(url)
    # 显式等待30秒,直到第一个航班卡片出现(用页面实际存在的元素定位器)
    wait = WebDriverWait(driver, 30)
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.gws-flights-explore__result-card')))
    
    # 额外等待页面所有请求完成
    wait.until(lambda d: d.execute_script('return document.readyState') == 'complete')
    
    # 现在获取的page_source应该包含渲染后的DOM了
    print(driver.page_source)
finally:
    driver.quit()

2. 确保ChromeDriver与Chrome版本完全匹配

这是很多人忽略的关键点:如果你的Chrome浏览器和ChromeDriver版本不兼容,会直接导致页面渲染异常,拿不到动态内容。你可以:

  • 打开Chrome,在chrome://settings/help查看当前版本(比如114.0.5735.198)
  • 下载对应大版本号的ChromeDriver(比如114.x的驱动对应114.x的Chrome)

3. 处理可能的反爬机制

Google Flights会检测自动化工具,你可以尝试:

  • 优先不用无头模式;如果必须用,改用新版无头模式参数:options.add_argument('--headless=new')(旧版无头模式更容易被检测)
  • 模拟人类行为,比如等待几秒后滚动页面:driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

为什么你的原代码不行?

implicitly_wait(20)只是告诉Selenium:如果找不到元素,最多等20秒再抛出异常。但它不会等待页面的动态AJAX请求完成,所以当你调用print(driver.page_source)时,页面可能还在加载航班数据,自然只能拿到未渲染的脚本内容。

内容的提问来源于stack exchange,提问作者Rafi Ramadhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:52