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

如何抓取鼠标悬停后弹出的多组日期与价格数据点?

解决Prishistorik价格历史数据抓取问题

问题分析

你的代码仅能获取一条数据,核心原因有两点:

  1. 元素定位错误:你用CSS选择器选中的rect元素是图表的背景容器,而非单个价格数据点,导致prices列表仅包含一个元素;
  2. 悬停后元素定位不稳定:固定的长XPath易受页面结构变化影响,且未确保悬停后弹出框完全加载。

解决方案一:修正Selenium元素定位与悬停逻辑

步骤1:定位正确的数据点元素

打开目标页面开发者工具,检查Prishistorik图表,会发现每个价格点对应<circle>标签(或带特定class的元素),需替换原选择器为数据点的定位规则。

步骤2:优化后的代码

from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, StaleElementReferenceException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("start-maximized")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)

DRIVER_PATH = r'd:\8278\Downloads\chromedriver.exe'

browser = webdriver.Chrome(options=chrome_options, executable_path=DRIVER_PATH)
browser.get("https://prisjagt.dk/lyd-billede/horetelefoner-tilbehor/hovedtelefoner/apple-airpods-pro-2nd-generation-2022--p7054034")
browser.maximize_window()

explicit_wait20 = WebDriverWait(browser, 20)
price_history_data = []

try:
    # 等待价格图表容器加载
    chart_container = explicit_wait20.until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, '.PriceHistoryWrapper-sc-1yjg8cb-3.ejhsba'))
    )
    # 定位所有价格数据点(以circle为例,需根据实际DOM调整)
    data_points = explicit_wait20.until(
        EC.visibility_of_all_elements_located((By.CSS_SELECTOR, '.PriceHistoryWrapper-sc-1yjg8cb-3.ejhsba svg g circle'))
    )
    
    for point in data_points:
        try:
            # 模拟悬停并等待弹出框渲染
            ActionChains(browser).move_to_element(point).pause(0.5).perform()
            # 定位弹出框并提取文本
            tooltip = WebDriverWait(browser, 5).until(
                EC.visibility_of_element_located((By.CSS_SELECTOR, '.PriceHistoryTooltip-sc-1yjg8cb-4'))
            )
            # 分割日期与价格,整理为结构化数据
            date, price = tooltip.text.split('\n')
            price_history_data.append({"日期": date, "价格": price})
        except (TimeoutException, StaleElementReferenceException):
            # 跳过无法获取的异常点
            continue

finally:
    browser.quit()

# 输出所有抓取到的数据
for item in price_history_data:
    print(f"{item['日期']}: {item['价格']}")

关键优化点

  • 用短class选择器替代冗长层级CSS,避免页面结构变动导致定位失效;
  • 加入pause(0.5)确保悬停后弹出框完全渲染;
  • 捕获元素过期异常,避免单次失败中断整个抓取流程;
  • 将弹出框文本分割为日期和价格,输出结构化数据。

解决方案二:直接提取页面JS数据(更高效稳定)

多数图表数据会预先存储在页面JS变量中,无需模拟鼠标操作,直接提取即可:

from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("start-maximized")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)

DRIVER_PATH = r'd:\8278\Downloads\chromedriver.exe'

browser = webdriver.Chrome(options=chrome_options, executable_path=DRIVER_PATH)
browser.get("https://prisjagt.dk/lyd-billede/horetelefoner-tilbehor/hovedtelefoner/apple-airpods-pro-2nd-generation-2022--p7054034")

# 执行JS脚本提取价格历史(变量名需根据实际页面调整)
price_history = browser.execute_script("""
    const productData = window.__NEXT_DATA__.props.pageProps.product;
    return productData.priceHistory;
""")

# 整理并输出数据
for entry in price_history:
    date = entry['date']
    price = f"{entry['price']} kr"
    print(f"{date}: {price}")

browser.quit()

优势

  • 无需模拟鼠标悬停,抓取速度更快、稳定性更高;
  • 直接获取原始结构化数据,无需处理文本分割。

内容的提问来源于stack exchange,提问作者R. Plate

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:20:26