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

Selenium间歇性无法获取页面中JavaScript注入的venueProfile数据

如何确保Selenium爬取时JavaScript生成的venueProfile数据稳定加载?

问题描述

我用Selenium爬取页面https://www-eur.cvent.com/venues/en-US/dubai/hotel/delano-dubai/venue-12d8dd54-25d5-49f8-99a0-d292e52f3b34,目标是提取JavaScript注入到页面的venueProfile JSON数据,通过driver.page_source配合正则表达式查找。但现在的问题是,页面源码里有时能找到venueProfile字符串,有时找不到——原本以为用WebDriverWait等待<body>加载完成就能确保数据存在,但实际效果不稳定。

已尝试的操作

  • 确认浏览器开发者工具中确实存在该字符串
  • 失败时保存debug.html,确认源码中确实无该字符串
  • 添加10秒以上的固定延迟等待
  • 修改user-agent字符串为Mozilla/5.0
  • 验证无异常抛出,页面加载完成但数据缺失

最简复现代码

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import re

options = Options()
options.add_argument("--headless")
options.add_argument("user-agent=Mozilla/5.0")

driver = webdriver.Chrome(options=options)
driver.get("https://www-eur.cvent.com/venues/en-US/dubai/hotel/delano-dubai/venue-12d8dd54-25d5-49f8-99a0-d292e52f3b34")

WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)

html = driver.page_source

match = re.search(r'"venueProfile":"(.*?)"', html)
print("Found" if match else "Not found")

driver.quit()

解决方案与最佳实践

1. 直接等待目标数据/JS变量加载完成

不要等待<body>这种宽泛的条件,直接针对venueProfile做精准等待:

  • 检查页面源码中是否出现目标字符串:
WebDriverWait(driver, 20).until(
    lambda driver: '"venueProfile"' in driver.page_source
)
  • 如果venueProfile是挂载在window对象下的JS变量,直接检查变量是否存在:
WebDriverWait(driver, 20).until(
    lambda driver: driver.execute_script('return typeof window.venueProfile !== "undefined";')
)

2. 等待包含目标数据的DOM元素

这类JS注入的数据通常会放在<script>标签里,直接等待该标签出现:

WebDriverWait(driver, 20).until(
    EC.presence_of_element_located((By.XPATH, '//script[contains(text(), "venueProfile")]'))
)

3. 优化无头模式配置,模拟真实浏览器

无头模式下的渲染逻辑和正常浏览器有差异,添加这些参数提升兼容性:

options = Options()
options.add_argument("--headless=new")  # 新版无头模式,更接近正常Chrome
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")  # 避免响应式布局影响渲染
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36")

4. 直接通过JS提取数据,避免依赖page_source

既然数据是JS生成的,直接在浏览器执行JS获取,比正则解析更可靠:

# 如果venueProfile是window下的对象
venue_data = driver.execute_script('return window.venueProfile;')

# 如果数据在script标签内,先获取标签内容再解析
script_tag = driver.find_element(By.XPATH, '//script[contains(text(), "venueProfile")]')
script_content = script_tag.get_attribute('innerHTML')
# 再用正则或JSON库解析内容
match = re.search(r'"venueProfile":"(.*?)"', script_content)

5. 添加重试机制应对偶发失败

如果偶尔还是会出现加载失败,加个重试逻辑:

import time

max_retries = 3
retry_count = 0
match = None

while retry_count < max_retries and not match:
    html = driver.page_source
    match = re.search(r'"venueProfile":"(.*?)"', html)
    if not match:
        time.sleep(2)
        retry_count += 1

print("Found" if match else "Not found after retries")

优化后的完整代码示例

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import re

options = Options()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36")

driver = webdriver.Chrome(options=options)
driver.get("https://www-eur.cvent.com/venues/en-US/dubai/hotel/delano-dubai/venue-12d8dd54-25d5-49f8-99a0-d292e52f3b34")

# 等待目标数据出现
WebDriverWait(driver, 20).until(
    lambda driver: '"venueProfile"' in driver.page_source
)

html = driver.page_source
match = re.search(r'"venueProfile":"(.*?)"', html)
print("Found" if match else "Not found")

driver.quit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:24:51