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

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

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

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

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

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

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

from selenium import webdriverfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.chrome.service import Servicefrom selenium.webdriver.chrome.options import Optionsfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as EC# 初始化WebDriveroptions = 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变量。

以目标网站为例,图表数据通常以类似dataArray.push({x: …, y: …})的格式存储在标签中。我们可以利用Python的requests库获取页面HTML,然后使用正则表达式re模块来匹配并提取这些数据。

核心步骤:

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

示例代码:

import reimport pandas as pdimport requests# 目标URLurl = "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   price236 2023-05-28 06:00:00  317.86237 2023-05-29 06:00:00  319.43238 2023-05-30 06:00:00  429.99239 2023-05-31 06:00:00  314.64240 2023-06-01 06:00:00   318.9

优势与注意事项

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

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

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

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

总结

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

以上就是如何高效抓取网页图表中的动态数据的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1365855.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 04:50:23
下一篇 2025年12月14日 04:50:37

相关推荐

  • Python解析自定义类Lua配置文件:递归策略与实现

    本教程详细介绍了如何使用Python解析一种非标准、类似Lua表格的自定义配置文件格式。针对传统JSON或AST解析方法无法直接处理的特点,文章提出并实现了基于递归函数的行级解析策略,能够有效识别嵌套结构,并构建出对应的Python字典。教程包含详细代码示例、使用方法及数据类型处理的注意事项,旨在提…

    好文分享 2025年12月14日
    000
  • 解析非标准配置文件的递归方法:以Lua风格数据为例

    本文旨在介绍如何使用Python解析一种非标准、类似Lua表结构的自定义配置文件。针对无法直接通过JSON或Python内置函数处理的复杂嵌套格式,我们将详细讲解一种基于递归函数的逐行解析策略,并通过示例代码展示如何构建一个能够识别键值对和嵌套字典的自定义解析器,并讨论其应用与潜在优化点。 1. 问…

    2025年12月14日
    000
  • Python网络爬虫:高效提取图表数据,告别鼠标悬停烦恼

    本教程探讨了在网页爬取中,如何高效地从图表数据中提取价格和日期信息。针对传统Selenium模拟鼠标悬停的局限性,我们提出了一种更优化的方法,即通过分析页面HTML源,直接利用requests库获取页面内容,并结合正则表达式re模块精确匹配并提取JavaScript中嵌入的数据,最终使用pandas…

    2025年12月14日
    000
  • Python怎样检测5G网络切片中的性能异常?

    #%#$#%@%@%$#%$#%#%#$%@_23eeeb4347bdd26bfc++6b7ee9a3b755dd能有效检测5g网络切片性能异常,因其具备实时数据流分析、机器学习算法应用及多接口集成能力。1. 数据采集:通过requests、grpcio接入rest/grpc api;conflue…

    2025年12月14日 好文分享
    000
  • 如何使用Python构建工业机器人的异常轨迹检测?

    工业机器人异常轨迹检测需关注位置、速度、加速度、力矩、轨迹一致性等关键特征。1)位置和姿态数据反映空间状态,结合速度与加速度可提前预警异常;2)关节力矩和电机电流揭示内部受力变化,有助于发现机械问题;3)轨迹重复性与偏差分析确保执行任务的稳定性;4)多维特征关联性识别复杂异常模式。针对模型选择,1)…

    2025年12月14日 好文分享
    000
  • 解析非标准Python字典式配置文件:一种递归式行处理方法

    本文介绍了一种解析非标准Python字典式配置文件的有效方法。针对无法直接使用json或ast.literal_eval处理的[“key”] = value格式配置,我们提出并实现了一个递归函数,通过逐行迭代和模式匹配,精确识别并构建嵌套的配置数据结构,从而将复杂文本转换为可…

    2025年12月14日
    000
  • 解决YOLOv7中’torchvision::nms’ CUDA后端兼容性问题

    本文旨在解决在YOLOv7中运行detect.py时遇到的NotImplementedError: Could not run ‘torchvision::nms’ with arguments from the ‘CUDA’ backend错误。该错…

    2025年12月14日
    000
  • Python虚拟环境怎么用?隔离项目依赖

    python虚拟环境通过隔离项目依赖解决版本冲突问题。其核心使用流程为:①创建虚拟环境,进入项目目录后执行python3 -m venv venv;②激活环境,在macos/linux用source venv/bin/activate,windows cmd用venvscriptsactivate.…

    2025年12月14日 好文分享
    000
  • Python怎样构建基于知识图谱的异常关联推理?

    要构建基于知识图谱的异常关联推理系统,核心在于将孤立事件编织为语义网络以揭示因果链和关联模式,其步骤如下:1. 从异构数据源中整合信息并抽取实体关系,涉及规则匹配、nlp技术如ner和re;2. 构建图谱结构并选择存储方案,小规模可用networkx,大规模则用neo4j等图数据库;3. 定义异常模…

    2025年12月14日 好文分享
    000
  • 怎样用Python构建分布式异常检测系统?Dask应用

    传统异常检测方法在大数据场景下受限于内存和计算能力,难以处理海量数据,而dask通过分布式计算突破这一瓶颈。dask利用任务图和懒惰计算机制,将数据和计算分解为可并行的小任务,调度至集群执行,实现内存溢出规避和高效并行。核心技术包括dask dataframe和array用于数据处理,dask-ml…

    2025年12月14日 好文分享
    000
  • Python如何做数据清洗?预处理缺失值方法

    数据清洗中的缺失值预处理主要包括识别、分析、选择策略并执行。1. 识别缺失值:使用isnull()或isna()判断缺失情况,并用sum()统计缺失数量。2. 分析缺失模式:判断缺失是否随机,是否与其他列有关联。3. 选择处理策略:包括删除(dropna)和填充(fillna)。删除适用于缺失值较少…

    2025年12月14日 好文分享
    000
  • 如何用Dask实现TB级数据的分布式异常扫描?

    dask处理tb级数据的分布式异常扫描的核心优势在于其分布式计算和惰性计算机制。1. 分布式计算突破单机内存限制,将数据拆分为多个分区并行处理;2. 惰性计算避免一次性加载全部数据,按需执行任务;3. 与pandas、numpy、scikit-learn等python生态无缝集成,降低学习成本;4.…

    2025年12月14日 好文分享
    000
  • Python中如何检测高维数据的局部异常模式?

    在python中检测高维数据的局部异常模式,推荐使用局部异常因子(lof)算法;2. lof通过比较样本点与其k近邻的局部可达密度(lrd)来识别异常,lof值远大于1表示该点为局部异常;3. 实际操作步骤包括:生成高维数据、初始化并训练lof模型、根据lof分数识别异常点;4. lof的关键参数包…

    2025年12月14日 好文分享
    000
  • Python多线程如何实现?并发编程入门指南

    python多线程并不能真正实现并行计算,尤其在cpu密集型任务中,由于全局解释器锁(gil)的存在,多线程无法同时利用多个cpu核心,因此大多数情况下不能提高程序运行速度;但在i/o密集型任务中,如网络请求、文件读写等,线程在等待i/o时会释放gil,从而实现“并发”提升效率;1. 多线程适用于i…

    2025年12月14日 好文分享
    000
  • Python怎样检测数据中的上下文异常?条件概率法

    条件概率法在上下文异常检测中有效,因为它直接评估数据点在特定上下文下的出现概率,从而识别出在孤立状态下正常但在特定语境下异常的数据点。1. 首先定义上下文,需结合领域知识,如时间窗口、环境参数等;2. 建立模型估计条件概率p(数据点|上下文),离散数据可用频率统计,连续数据可用kde或gmm等方法;…

    2025年12月14日 好文分享
    000
  • Python如何实现快速排序?分治算法解析

    快速排序在python中的核心思想是“分而治之”。1. 它通过选择一个“基准”元素,将数组分为小于基准和大于基准的两部分;2. 然后递归地对这两部分继续排序,直到整个数组有序;3. 实现中使用主函数quick_sort和递归辅助函数_quick_sort_recursive,分区函数_partiti…

    2025年12月14日 好文分享
    000
  • Python怎样计算数据的几何平均数?

    在python中计算几何平均数,推荐使用scipy.stats.gmean函数,也可通过数学方法手动实现。1. 使用scipy.stats.gmean:直接调用该函数可高效处理数据列表或numpy数组,适用于正数数据集。2. 手动实现:基于对数转换,使用math库计算log和exp,避免浮点数溢出问…

    2025年12月14日 好文分享
    000
  • Python中如何识别可能的内存密集型操作?

    python程序中内存密集型操作的识别和优化需从数据结构、函数调用、i/o模式、对象生命周期等多个维度入手。1. 首先,关注大规模数据结构的使用,如巨型列表或字典,应考虑分批处理或使用生成器。2. 其次,频繁的字符串拼接会导致大量临时对象产生,建议使用join()方法。3. 对象的引用和生命周期管理…

    2025年12月14日 好文分享
    000
  • 使用Python解析自定义配置文件:一种递归方法

    本文旨在介绍一种高效且灵活的Python递归解析方法,用于处理非标准、类字典格式的配置文件。通过逐行读取文件内容,并利用递归函数处理嵌套结构,该方法能够准确地将自定义格式的数据转换为Python字典,尤其适用于处理键值对以[“key”] = value形式表示,且包含布尔值、…

    2025年12月14日
    000
  • 解析类Lua配置文件的Python实现

    本文详细介绍了如何使用Python解析一种非标准、类Lua语法的配置文件。针对传统方法如json或ast.literal_eval的局限性,文章提出了一种基于递归函数和行迭代的解析策略,能够有效处理嵌套字典结构,并提供了完整的代码示例和使用说明,旨在帮助开发者灵活读取自定义格式的配置数据。 理解自定…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信