0

0

如何高效抓取网页图表中的动态数据

DDD

DDD

发布时间:2025-07-20 14:22:15

|

1027人浏览过

|

来源于php中文网

原创

如何高效抓取网页图表中的动态数据

本文旨在探讨从网页动态图表中高效提取数据的方法。针对鼠标悬停显示数据的场景,我们将对比传统的Selenium模拟交互方式与更优的直接解析HTML中嵌入的JavaScript数据的方法。通过实际案例,我们将展示如何利用Python的requests、re和pandas库,直接从网页源代码中提取并结构化图表数据,从而避免复杂的浏览器自动化操作,提高数据抓取的效率和稳定性。

在进行网页数据抓取时,我们经常会遇到动态加载或通过JavaScript渲染的内容,尤其是那些以图表形式展示的数据,如历史价格曲线、性能指标等。这些数据往往在用户鼠标悬停时才以工具提示(tooltip)的形式显示,这给传统的爬虫带来了挑战。

挑战:使用Selenium模拟鼠标悬停抓取动态数据

许多初学者在面对这类问题时,自然会想到使用Selenium等浏览器自动化工具来模拟用户行为。例如,对于一个展示CPU价格历史的图表,尝试通过模拟鼠标悬停在图表上的每一个点来获取对应的价格和日期信息。

以下是一个尝试使用Selenium模拟鼠标悬停的示例代码:

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

# 初始化WebDriver
options = Options()
options.add_argument("start-maximized")
webdriver_service = Service()
driver = webdriver.Chrome(options=options, service=webdriver_service)

# 访问目标网页
driver.get('https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i9-11900K+%403.50GHz&id=3904')

# 等待图表元素加载
# 注意:EC.presence_of_element_located 返回的是单个WebElement对象
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[@id='placeholder']/div/canvas[2]")))

# 尝试遍历元素(此处会报错,因为element是单个WebElement,不可迭代)
# for el in element:
#     ActionChains(driver).move_to_element(el).perform()
#     mouseover = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".placeholder > div > div.canvasjs-chart-tooltip > div > span")))
#     print(mouseover.text)

上述代码中存在一个常见错误:WebDriverWait.until(EC.presence_of_element_located(...))方法返回的是一个WebElement对象,代表页面上找到的第一个匹配元素,而不是一个可迭代的元素列表。因此,直接对其进行for el in element:循环会导致'WebElement' object is not iterable的运行时错误。

更重要的是,即使修复了迭代问题,通过模拟鼠标悬停来逐点抓取图表数据,效率也极其低下且不稳定。页面渲染、动画效果和JavaScript执行的延迟都可能导致抓取失败或数据不完整。

解决方案:直接解析HTML中的JavaScript数据

对于许多动态图表,其数据往往直接嵌入在页面的JavaScript代码中,而不是通过Ajax请求动态加载。在这种情况下,最有效且高效的方法是直接从网页的HTML源代码中提取这些JavaScript变量。

极品模板多语言企业网站管理系统1.2.2
极品模板多语言企业网站管理系统1.2.2

【极品模板】出品的一款功能强大、安全性高、调用简单、扩展灵活的响应式多语言企业网站管理系统。 产品主要功能如下: 01、支持多语言扩展(独立内容表,可一键复制中文版数据) 02、支持一键修改后台路径; 03、杜绝常见弱口令,内置多种参数过滤、有效防范常见XSS; 04、支持文件分片上传功能,实现大文件轻松上传; 05、支持一键获取微信公众号文章(保存文章的图片到本地服务器); 06、支持一键

下载

以目标网站为例,图表数据通常以类似dataArray.push({x: ..., y: ...})的格式存储在

核心步骤:

  1. 获取网页内容: 使用requests库发送HTTP GET请求,获取目标URL的HTML源代码。
  2. 查找数据模式: 分析HTML源代码,定位包含图表数据的JavaScript代码块。识别数据点的通用模式,例如{x: 时间戳, y: 价格}。
  3. 使用正则表达式提取: 编写正则表达式来匹配并捕获这些数据点中的时间戳和价格值。
  4. 结构化数据: 将提取到的数据转换为结构化的格式,例如Pandas DataFrame,以便后续分析。
  5. 数据类型转换: 对提取到的时间戳进行转换,使其变为可读的日期时间格式。

示例代码:

import re
import pandas as pd
import requests

# 目标URL
url = "https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i9-11900K+%403.50GHz&id=3904"

# 使用requests获取网页HTML内容
html_text = requests.get(url).text

# 使用正则表达式从HTML中查找并提取数据
# 模式解释:
# dataArray\.push\({x: (\d+), y: ([\d.]+)}
# - dataArray\.push\({x: : 匹配字面字符串 "dataArray.push({x: "
# - (\d+) : 捕获一个或多个数字(时间戳)
# - , y: : 匹配字面字符串 ", y: "
# - ([\d.]+) : 捕获一个或多个数字或点(价格,可能包含小数点)
# - } : 匹配字面字符串 "}"
df = pd.DataFrame(
    re.findall(r"dataArray\.push\({x: (\d+), y: ([\d.]+)}", html_text),
    columns=["time", "price"],
)

# 将时间戳(Unix时间戳,通常是毫秒)转换为可读的日期时间格式
# 网站给出的时间戳是毫秒,需要除以1000转换为秒
df["time"] = pd.to_datetime(df["time"].astype(int) // 1000, unit="s")

# 打印数据框的最后几行以验证结果
print(df.tail())

运行结果示例:

                   time   price
236 2023-05-28 06:00:00  317.86
237 2023-05-29 06:00:00  319.43
238 2023-05-30 06:00:00  429.99
239 2023-05-31 06:00:00  314.64
240 2023-06-01 06:00:00   318.9

优势与注意事项

这种直接解析JavaScript数据的方法具有显著优势:

  • 高效性: 无需启动浏览器,大大减少了资源消耗和运行时间。
  • 稳定性: 不依赖于页面渲染和JavaScript执行的复杂性,减少了因页面加载延迟或元素定位不准导致的错误。
  • 简洁性: 代码逻辑更清晰,易于维护。

然而,此方法并非万能,有其适用范围和注意事项:

  • 适用场景: 主要适用于数据直接嵌入在HTML源代码的
  • 不适用场景:
    • 数据通过复杂的AJAX请求在页面加载后异步获取,且这些请求的URL和参数难以推断。
    • 数据经过高度混淆或加密,难以通过正则表达式直接解析。
    • 需要模拟用户登录、表单提交、点击按钮等复杂交互才能获取数据的情况。
  • 正则表达式的健壮性: 正则表达式需要根据目标网站的HTML结构和JavaScript代码模式进行定制。如果网站结构发生变化,正则表达式可能需要调整。
  • 数据清洗: 提取出的数据可能需要进一步的清洗和类型转换,例如时间戳转换、数值类型转换等。

总结

在进行网页数据抓取时,面对动态内容,我们应优先考虑从网页源代码中直接提取数据。相比于依赖Selenium模拟复杂的用户交互,直接解析HTML中嵌入的JavaScript数据通常是更高效、稳定且资源友好的选择。只有当数据确实无法通过静态解析获取,或者需要模拟复杂的浏览器行为时,才考虑使用Selenium等浏览器自动化工具。理解这两种方法的优劣和适用场景,是成为一名高效网络爬虫开发者的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

159

2023.06.14

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

160

2023.08.31

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

117

2023.11.15

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

235

2024.09.24

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

514

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

251

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

748

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

215

2023.08.11

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

0

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

CSS教程
CSS教程

共754课时 | 25.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号