针对xpath局限的解决方案
上篇《网页数据提取利器 -- Xpath》我们对xpath的介绍中提到了xpath的几点局限性:
- 结构依赖性强
- 性能
- 动态网页支持不足
本篇是针对这些局限提出的解决方案和补充方法,以提升 XPath 的实用性和适应性。
1. 动态网页的处理
局限:
XPath 无法直接处理通过 JavaScript 动态生成的内容,因为其依赖于静态的 HTML 结构。
补充方法:
-
结合浏览器自动化工具: 使用 Selenium 等工具加载动态网页,获取最终渲染的 HTML 内容,然后再应用 XPath 进行解析。
from selenium import webdriver from lxml import etreedriver = webdriver.Chrome() driver.get("https://example.com")# 获取动态加载后的页面内容 page_source = driver.page_source# 使用 lxml 解析并应用 XPath tree = etree.HTML(page_source) dynamic_content = tree.xpath('//div[@class="dynamic-content"]/text()') print(dynamic_content)driver.quit() -
借助 Puppeteer: 如果使用 JavaScript,可以通过 Puppeteer 操控浏览器,执行 JavaScript 后再提取 HTML,结合 XPath 定位。
2. 结构依赖性强
局限:
XPath 对页面结构的依赖性较高,页面结构稍有改动,可能导致 XPath 表达式失效。
补充方法:
-
尽量使用更通用的定位方式: 避免过多依赖具体的层级结构,多使用属性或关键节点。例如:
# 不推荐的方式 /html/body/div[1]/div[2]/p# 推荐的方式 //div[@class='content']/p
-
结合 CSS 选择器: 在某些场景下,CSS 选择器比 XPath 更灵活且不依赖层级。例如:
- XPath:
//div[@class='item'] - CSS:
div.item
如果工具支持 CSS 和 XPath 两种方式,可以选择最稳定的一种。
- XPath:
-
动态生成 XPath: 根据页面的属性动态生成 XPath。例如:
def generate_xpath(tag, attr, value):return f"//{tag}[@{attr}='{value}']"xpath = generate_xpath("div", "class", "content")
3. 性能问题
局限:
对于大型文档或复杂结构,XPath 查询可能效率较低,特别是使用 // 选择器时。
补充方法:
-
减少范围: 在确定范围的前提下,尽量缩小搜索范围。例如:
# 慎用 //div[@class='content']# 优化 /html/body/div[@class='content']
-
分段解析: 如果文档非常大,可以分段加载并解析,减少内存占用和查询时间。
-
使用更高效的工具: 如果性能瓶颈严重,可以使用更高效的解析工具,如
BeautifulSoup中的 CSS 选择器,或结合正则表达式。
4. 不支持复杂逻辑
局限:
XPath 对复杂逻辑的支持有限,如无法直接实现跨节点的动态条件筛选。
补充方法:
-
结合编程语言的逻辑: 通过 Python 等语言对提取结果进行二次处理。
elements = tree.xpath('//div[@class="item"]') filtered = [el for el in elements if "special" in el.text] -
结合 XPath 2.0 或 XQuery: XPath 1.0 功能有限,部分场景下可以尝试支持 XPath 2.0 的工具,如 Saxon 或 BaseX。这些工具支持更多的函数和复杂逻辑。
5. 处理嵌套数据的困难
局限:
XPath 对复杂嵌套的数据结构处理可能不直观,特别是嵌套关系深且不规则时。
补充方法:
-
逐步定位嵌套节点: 将复杂的嵌套查询分解为多步处理。例如:
parent_nodes = tree.xpath('//div[@class="parent"]') for parent in parent_nodes:child_nodes = parent.xpath('./div[@class="child"]') -
结合 JSON 解析: 如果嵌套数据可以以 JSON 格式呈现,可以先将其转换为 JSON,再进行解析和提取。
6. 跨节点依赖
局限:
XPath 无法在同一级别的节点间动态比较或选择。
补充方法:
-
编程语言辅助: 通过遍历和编程逻辑解决跨节点比较问题。例如,找到同一层级中文本值最大的节点:
nodes = tree.xpath('//item') max_node = max(nodes, key=lambda node: int(node.text)) -
借助 XSLT: XSLT 是 XML 转换语言,可以处理更复杂的跨节点依赖。
7. 动态生成的属性名或节点名
局限:
在某些情况下,属性名或节点名是动态生成的,XPath 无法直接定位。
补充方法:
-
通配符: 使用
*选择动态节点。//div[@*='dynamic_value'] -
正则表达式: XPath 本身不支持正则,但结合工具(如 lxml 的
re模块扩展)可以实现:from lxml import etree from lxml.html import fromstringhtml = '<div id="dynamic123">Content</div>' tree = fromstring(html)# 正则匹配 ID 动态部分 dynamic_node = tree.xpath("//div[re:match(@id, 'dynamic\d+')]",namespaces={"re": "http://exslt.org/regular-expressions"})
总结
XPath 的局限性可以通过结合其他工具和方法进行弥补:
- 结合动态渲染工具(Selenium、Puppeteer),处理动态网页。
- 优化路径表达式,避免深层级依赖和性能问题。
- 利用编程语言逻辑,弥补复杂逻辑和跨节点依赖。
- 考虑其他技术(CSS 选择器、XQuery、正则),解决 XPath 无法胜任的场景。
在实际应用中,灵活选择技术组合是应对 XPath 局限的关键。
相关文章:
针对xpath局限的解决方案
上篇《网页数据提取利器 -- Xpath》我们对xpath的介绍中提到了xpath的几点局限性: 结构依赖性强性能动态网页支持不足 本篇是针对这些局限提出的解决方案和补充方法,以提升 XPath 的实用性和适应性。 1. 动态网页的处理 局限: XPath 无法…...
深入解析 HTML Input 元素:构建交互性表单的核心
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
ffmpeg转码与加水印
文章目录 转码 与加水印引入jar包代码ffmpeg安装错误解决方法 转码 与加水印 引入jar包 <dependency><groupId>net.bramp.ffmpeg</groupId><artifactId>ffmpeg</artifactId><version>0.6.2</version></dependency>代码 impo…...
Leetcode 104. 二叉树的最大深度(Java-深度遍历)
题目描述: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例: 输入:root [3,9,20,null,null,15,7] 输出:3示例 2: 输入:…...
阳明心学-传习录学习总结
资料 王阳明介绍:明代杰出的思想家、军事家、教育家;自刑部主事历任贵州龙场驿丞、庐陵知县、右佥都御史、南赣巡抚、两广总督等职,接连平定南赣、两广盗乱及宸濠之乱,因功获封“新建伯”,成为明代因军功封爵的三位文…...
macOS sequoia 15.1中应用程序“程序坞”没有权限打开
在macOS sequoia 15.1版本中新安装的应用程序在访达中打开报错显示应用程序“程序坞”没有权限打开“(null)”。 解决办法 在启动台中找到终端,点击打开,切换到应用目录下,输入 cd /Applications/ 找到需要打开的应用程序目录࿰…...
使用 MinIO 和 KKFileView 实现在线文件预览功能
在项目开发中,文件的在线预览是常见的需求,尤其是对 PDF、Word、Excel 等格式的文件进行无客户端依赖的直接查看。本文将介绍如何通过 MinIO 和 KKFileView 搭建在线文件预览服务,并通过 docker-compose 一键部署。 一、环境准备 1. Docker …...
Conda-Pack打包:高效管理Python环境
在Python开发中,环境管理是一个不可忽视的重要环节。Conda是一个流行的包管理器和环境管理器,它允许用户创建隔离的环境,以避免不同项目之间的依赖冲突。Conda-pack是一个工具,可以帮助我们将一个conda环境打包成一个可移植文件&a…...
云服务器上搭建 WordPress 全流程指南
WordPress 是全球最受欢迎的开源内容管理系统(CMS),通过 WordPress,你可以轻松搭建博客、企业网站或电子商务平台。而通过云服务器搭建 WordPress,可以使网站获得更好的性能和灵活性。本文将为你提供详细的步骤&#x…...
图像超分辨率技术新进展:混合注意力聚合变换器HAAT
目录 1. 引言: 2. 混合注意力聚合变换器(HAAT): 2.1 Swin-Dense-Residual-Connected Block(SDRCB): 2.2 Hybrid Grid Attention Block(HGAB): 3. 实验结…...
文件IO——01
1. 认识文件 1)文件概念 “文件”是一个广义的概念,可以代表很多东西 操作系统里,会把很多的硬件设备和软件资源抽象成“文件”,统一管理 但是大部分情况下的文件,都是指硬盘的文件(文件相当于是对“硬…...
【opencv入门教程】5. Mat 类用法
文章选自: 一、BackGround Mat对象是一种图像数据结构,它是一个容器,存储任何通道任何数的图片数据以及对应的矩阵,使用完成后,内存自动释放。二、Code void Samples::MatFunc() {1. 图像处理// 方法1:…...
SSM虾米音乐项目2--分页查询
1.分页查询的底层逻辑 首先根据用户输入的流派,进行模糊查询根据查询的数据进行分页需要前端用户提供pageNo(当前页数)和pageSize(每页的数据量)并且要从后端计算count(总数据量)和totalPage(总页数),以及startNum(每页开始的记录)从而将对应的页面数据…...
nodejs 获取本地局域网 ip 扫描本地端口
因为傻逼老板的垃圾需求,不得不成长 示例代码: 获取本地局域网 ip 地址: 需要注意的是:如果存在虚拟机网络,则返回的是虚拟机网络的 ipv4 地址 import os from os; export const getLocalIp () > {const in…...
区块链签名种类
1. eth_sign 简介:最早实现的签名方法,用于对任意数据进行签名。签名内容:直接对原始消息的哈希值进行签名。特点: 安全性较低,因为签名的消息没有明确的上下文或结构。很容易被滥用,攻击者可以伪造签名内…...
【062B】基于51单片机无线病房呼叫系统(+时间)【Keil程序+报告+原理图】
☆、设计硬件组成:51单片机最小系统NRF24L01无线模块DS1302时钟芯片LCD1602液晶显示按键设置蜂鸣器LED灯。 1、本设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片,采用LCD1602液晶显示呼叫信息,系统共有两个板子(一个接…...
突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!
文章链接:https://arxiv.org/pdf/2411.18623 项目链接:https://lift3d-web.github.io/ 亮点直击 提出了Lift3D,通过系统地提升隐式和显式的3D机器人表示,提升2D基础模型,构建一个3D操作策略。 对于隐式3D机器人表示&a…...
【pyspark学习从入门到精通24】机器学习库_7
目录 聚类 在出生数据集中寻找簇 主题挖掘 回归 聚类 聚类是机器学习中另一个重要的部分:在现实世界中,我们并不总是有目标特征的奢侈条件,因此我们需要回归到无监督学习的范式,在那里我们尝试在数据中发现模式。 在出生数据…...
Echart折线图属性设置 vue2
Echart折线图 官方配置项手册 Documentation - Apache ECharts 下面代码包含:设置标题、线条样式、图例圆圈的样式、显示名称格式、图片保存、增加Y轴目标值 updateChart(data) {const sortedData data.slice().sort((a, b) > new Date(a.deviceTime) - ne…...
LabVIEW-简单串口助手
LabVIEW-简单串口助手 串口函数VISA配置串口VISA写入函数VISA读取函数VISA资源名称按名称解除捆绑 函数存放位置思维导图主体界面为以下 串口函数 VISA配置串口 VISA写入函数 VISA读取函数 VISA资源名称 按名称解除捆绑 函数存放位置 思维导图 主体界面为以下 从创建好的“枚举…...
Z-Image-Turbo-rinaiqiao-huiyewunv 模型微调实战:使用自定义数据集训练专属风格
Z-Image-Turbo-rinaiqiao-huiyewunv 模型微调实战:使用自定义数据集训练专属风格 想不想让AI画出专属于你的独特风格?比如,你是一位插画师,希望AI能学会你笔下那种温暖治愈的线条;或者你经营一个品牌,需要…...
旧设备重生:如何让经典iOS设备突破系统限制重获新生?
旧设备重生:如何让经典iOS设备突破系统限制重获新生? 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …...
Go Routine 调度器任务执行机制
Go语言凭借其轻量级线程——Goroutine,成为高并发编程的热门选择。而Goroutine的高效执行,离不开Go调度器的精妙设计。本文将深入探讨Go调度器的任务执行机制,揭示其如何实现高效并发。 **Goroutine的轻量特性** Goroutine相比传统线程更加…...
从草图到文档:我用这5个Miro/PlantUML模板,高效搞定团队架构设计评审
从草图到文档:5个高效架构设计模板与团队协作实战指南 在敏捷开发环境中,架构设计往往陷入两难困境——既要快速响应需求变化,又要保证设计文档的准确性与可维护性。Tech Lead们经常面临这样的场景:在白板前与团队激情讨论出的架构…...
FastMoss TikTok电商数据爬取实战:JS逆向与MD5签名破解
1. FastMoss TikTok电商数据爬取的核心挑战 最近在研究FastMoss平台的TikTok电商数据爬取,发现最大的难点在于请求签名加密。当你访问https://www.fastmoss.com/zh/e-commerce/saleslist这个页面时,切换周榜会触发一个带有fm-sign签名的加密请求。这个签…...
SAP工单组件批量添加技巧:CO_XT_COMPONENT_ADD与CO_XT_ORDER_PREPARE_COMMIT组合使用教程
SAP工单组件批量添加实战:CO_XT_COMPONENT_ADD与CO_XT_ORDER_PREPARE_COMMIT深度解析 在SAP生产订单管理中,批量添加组件是制造企业常见的需求场景。当面对数百甚至上千个工单组件需要同时维护时,传统GUI操作不仅效率低下,还容易出…...
UltraStar Deluxe实战指南:免费打造专业级家庭KTV系统
UltraStar Deluxe实战指南:免费打造专业级家庭KTV系统 【免费下载链接】USDX The free and open source karaoke singing game UltraStar Deluxe, inspired by Sony SingStar™ 项目地址: https://gitcode.com/gh_mirrors/us/USDX 还在为KTV包厢的高昂费用而…...
别再手动写DSP了!Vivado里用Multiply Adder IP核实现MAC运算的保姆级教程
高效实现MAC运算:Vivado中Multiply Adder IP核的工程实践指南 在FPGA开发中,乘累加(MAC)运算作为数字信号处理的核心操作,其实现效率直接影响系统性能。传统手写RTL代码不仅耗时,还容易引入时序问题和资源浪…...
网易云音乐无损解析:从零打造个人音乐库的终极指南
网易云音乐无损解析:从零打造个人音乐库的终极指南 【免费下载链接】Netease_url 网易云无损解析 项目地址: https://gitcode.com/gh_mirrors/ne/Netease_url 还在为网易云音乐无法下载无损音质而烦恼吗?想要建立属于自己的高品质音乐收藏库吗&am…...
ROS2 核心概念与实战应用指南
1. ROS2核心概念解析:从零开始理解机器人开发框架 第一次接触ROS2时,我被它复杂的术语体系搞得晕头转向。直到把机器人项目比作一个餐厅,才突然开窍——节点就像厨师和服务员,话题是传菜窗口,服务是点单对讲机…...
