针对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资源名称 按名称解除捆绑 函数存放位置 思维导图 主体界面为以下 从创建好的“枚举…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...
