Scrapy与分布式开发(2.3):lxml+xpath基本指令和提取方法详解

lxml+xpath基本指令和提取方法详解

一、XPath简介

XPath,全称为XML Path Language,是一种在XML文档中查找信息的语言。它允许用户通过简单的路径表达式在XML文档中进行导航。XPath不仅适用于XML,还常用于处理HTML文档。

二、基本指令和提取方法

选择节点

使用XPath,你可以轻松地选择XML文档中的节点。
* 选择根节点:/
* 选择子节点:/parent/child
* 选择所有节点://*
* 后代节点选择:使用//descendant选择文档中的任意后代节点,无论层级。
* 相邻节点选择:使用/sibling1/following-sibling::sibling2选择相邻的同级节点。

使用轴

XPath提供了多种轴,允许你基于节点之间的关系进行选择。
* 子轴:/parent/child
* 同胞轴:/parent/child1/following-sibling::child2
* 属性轴:/parent/child/@attribute

使用谓语

谓语用于过滤节点集,帮助你更精确地定位节点。
* 选择第一个节点:/parent/child[1]
* 选择具有特定值的节点:/parent/child[@attribute='value']
* 选择多个满足条件的节点:/parent/child[position() > 1]
* 使用/parent/child/@attribute直接选择属性节点。
* 使用/parent/child[position()]根据节点在父节点下的位置进行选择。例如,[1]表示第一个子节点,[last()]表示最后一个子节点。
* 使用/parent/child[text()='value']选择文本内容等于特定值的节点。
* 使用andor进行多条件选择,如/parent/child[@attribute1='value1' and @attribute2='value2']

提取加粗样式文本

XPath不仅可以定位节点,还可以提取节点的文本内容。
* 使用text()函数提取节点的文本内容,如/parent/child/text()
* 使用string()函数提取节点的字符串表示,适用于复杂节点结构。
* 直接使用/@attribute提取节点的属性值,如/parent/child/@attribute
* 使用逗号,分隔多个XPath表达式,一次性提取多个节点或属性,如/parent/(child1, child2, @attribute)
* 使用.表示当前节点及其所有子节点,如node()函数。

三、实例演示

下面是一些XPath查询的实例,演示了如何使用XPath来提取XML文档中的数据。

XML文档示例

<bookstore><book><title lang="en">Harry Potter</title><author>J.K. Rowling</author><price>29.99</price></book><book><title lang="en">Learning XML</title><author>Erik T. Ray</author><price>39.95</price></book><book><title lang="zh-CN">西游记</title><author>吴承恩</author><price>28.80</price></book>
</bookstore>

选择所有书名
XPath表达式:/bookstore/book/title
结果:<title lang="en">Harry Potter</title>, <title lang="en">Learning XML</title>, <title lang="zh-CN">西游记</title>

选择第二本书的价格
XPath表达式:/bookstore/book[2]/price
结果:<price>39.95</price>

选择所有英文书名
XPath表达式:/bookstore/book/title[@lang='en']
结果:<title lang="en">Harry Potter</title>, <title lang="en">Learning XML</title>

选择价格高于30的所有书籍
XPath表达式:/bookstore/book[price > 30]
结果:<book>...</book>(包含Learning XML这本书的信息)

选择所有书籍的作者名字
XPath表达式:/bookstore/book/author/text()
结果:J.K. Rowling, Erik T. Ray, 吴承恩

选择第一本书的标题文本
XPath表达式:/bookstore/book[1]/title/text()
结果:Harry Potter

选择所有书籍的价格(作为文本)
XPath表达式:/bookstore/book/price/text()
结果:29.99, 39.95, 28.80

选择所有具有属性的title节点
XPath表达式://title[@*]
结果:所有带有属性的<title>节点,如<title lang="en">Harry Potter</title>

提取多个节点并返回其文本
XPath 表达式:/bookstore/book/(title/text(), author/text())
结果:对于每一本书,返回其标题和作者的文本内容,例如第一本书返回 ("Harry Potter", "J.K. Rowling")

提取节点的直接子节点
XPath 表达式:/bookstore/book/price
结果:返回所有<price>节点,因为<price><book>的直接子节点。

提取节点的所有子节点
XPath 表达式:/bookstore/book/*
结果:对于每一本书,返回其所有子节点,即<title>, <author>, 和 <price>

提取节点的属性
XPath 表达式:/bookstore/book/title/@lang
结果:返回所有<title>节点的lang属性值,例如"en""zh-CN"

提取节点的父节点
XPath 表达式:/bookstore/book/price/parent::book
结果:返回每个<price>节点的父节点<book>

提取节点的前一个或后一个同级节点
XPath 表达式:/bookstore/book[2]/title/previous-sibling::title/bookstore/book[2]/title/next-sibling::title
结果:分别返回第二本书标题的前一个和后一个同级标题节点(在这个例子中,因为第二本书是第一个,所以前一个同级节点不存在,后一个同级节点是第三本书的标题)。

提取节点的祖先节点
XPath 表达式:/bookstore/book/title/ancestor::bookstore
结果:返回每个<title>节点的祖先<bookstore>节点。

提取节点及其所有后代节点
XPath 表达式:/bookstore/book[1]
结果:返回第一本书及其所有后代节点,即完整的第一本书的信息。

提取满足条件的节点集合
XPath 表达式:/bookstore/book[price > 30]
结果:返回价格大于30的所有<book>节点。

四、lxml应用xpath

在Python中,lxml是一个功能强大的库,用于解析XML和HTML文档。结合XPath,我们可以轻松地定位和提取文档中的特定信息。下面是一个关于如何使用lxml和XPath进行XML解析和数据提取的详细讲解,重点在于提供实用指令和文本提取方法。

安装lxml

首先,确保你已经安装了lxml库。如果没有,可以通过pip进行安装:

pip install lxml

加载XML文档

使用lxmletree模块加载XML文档:

from lxml import etree
# 加载XML文档
tree = etree.parse('example.xml')

使用XPath提取数据

  1. 选择节点
    选择所有<book>节点:
books = tree.xpath('/bookstore/book')
  1. 选择特定节点
    选择第一个<book>节点:
first_book = tree.xpath('/bookstore/book[1]')
  1. 选择节点属性
    选择所有<book>节点的title属性值:
titles = tree.xpath('/bookstore/book/title/@lang')
  1. 选择节点的文本内容
    选择所有<title>节点的文本内容:
titles_text = tree.xpath('/bookstore/book/title/text()')
  1. 选择多个节点及其文本内容
    选择所有<book>节点的<title><author>文本内容:
books_info = tree.xpath('/bookstore/book/(title/text(), author/text())')
  1. 条件选择
    选择价格大于30的<book>节点:
expensive_books = tree.xpath('/bookstore/book[price > 30]')
  1. 选择后代节点
    选择所有<price>后代节点:
prices = tree.xpath('//price')

实战演示

案例一:提取博客文章标题
from lxml import etree  # 假设html_content是博客网页的HTML内容  
html_content = """  
<html>  
<head>  <title>My Blog</title>  
</head>  
<body>  <h1>Welcome to My Blog</h1>  <div class="post">  <h2>Article 1 Title</h2>  <p>Article 1 content...</p>  </div>  <div class="post">  <h2>Article 2 Title</h2>  <p>Article 2 content...</p>  </div>  
</body>  
</html>  
"""  # 解析HTML  
tree = etree.HTML(html_content)  # 使用XPath定位所有<h2>元素并提取文本内容  
article_titles = tree.xpath('//h2/text()')  # 打印文章标题  
for title in article_titles:  print(title.strip())  # 使用strip()移除可能存在的空白字符
案例二:提取链接和链接文本
from lxml import etree  html_content = """  
<html>  
<head>  <title>Links Page</title>  
</head>  
<body>  <p>Here are some links:</p>  <ul>  <li><a href="https://example.com/link1">Link 1</a></li>
<li><a href="https://example.com/link2">Link 2</a></li>  <li><a href="https://example.com/link3">Link 3</a></li>  </ul>  
</body>  
</html>  
"""  # 解析HTML  
tree = etree.HTML(html_content)  # 使用XPath提取所有链接和链接文本  
links = tree.xpath('//a')  
for link in links:  link_text = link.text.strip()  # 提取链接文本并移除空白字符  link_href = link.get('href')  # 提取href属性  print(f"Link Text: {link_text}, Link: {link_href}")
案例三:提取链接和链接文本
from lxml import etree  html_content = """  
<html>  
<head>  <title>Table Page</title>2</th>  <th>Header 3</th>  </tr>  <tr>  <td>Row 1, Col 1</td>  <td>Row 1, Col 2</td>  <td>Row 1, Col 3</td>  </tr>  <tr>  <td>Row 2, Col 1</td>  <td>Row 2, Col 2</td>  <td>Row 2, Col 3</td>  </tr>  </table>  
</body>  
</html>  
"""  # 解析HTML  
tree = etree.HTML(html_content)  # 使用XPath提取表格的所有行  
table_rows = tree.xpath('//table/tr')  # 遍历行并提取单元格数据  
for row in table_rows:  # 提取单元格数据,这里假设所有行都有相同数量的列  cells = row.xpath('td|th')  row_data = [cell.text.strip() for cell in cells]  print(row_data)

注意事项

  • XPath表达式是大小写敏感的,确保你的标签名与XML文档中的大小写一致。
  • 如果XML文档中有命名空间,你可能需要在XPath表达式中处理它们。

经验之谈

借用浏览器快速获取xpath指令

打开浏览器进入开发者模式,选定要提取的位置,然后右键按下图流程处理即可快速获取该位置的xpath选择命令
在这里插入图片描述

XPath Helper

浏览器插件XPath Helper可以让我们直观看到自己的选择命令是不是合理的
在这里插入图片描述

代码提取不到但是浏览器可以?

有时候会出现明明浏览器直接copy的指令,或者我们通过浏览器确定是可以的指令,但是在代码执行却提取失败,这种常见的可能性是:网页返回的html文本结构是A,但是经过浏览器渲染后变成了B,这让我们用B的指令去提取A,肯定得不到结果,这种在表格中比较常见,特别table > tbody > tr这一层,如果网页本身没有tbody,浏览器一般会自动渲染上。
解决方法:

  • 代码调试
  • 查看网页源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/731295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自编C++题目——几点了 hard ver.

题目难度 普及- 题目描述 一个老外用一口不流利的中文问你&#xff1a;“Xian zai ji dian le?”你看了一眼表&#xff0c;知道了现在是&#xff0c;你准备用这样的形式写在纸上&#xff1a; Now is m past/to h. 如果你看不懂&#xff0c;举个例子&#xff1a; 当h10&…

Rollup Summer:一览 Rollup 生态全景图

作者&#xff1a;Stanley&#xff0c;Kernel Ventures 编译&#xff1a;JIN&#xff0c;Techub News 短短几天内&#xff0c;ZKFair 的总锁定价值&#xff08;TVL&#xff09;已达到 1.2 亿美元&#xff0c;目前稳定在 8000 万美元&#xff0c;使其成为增长最快的 Rollup 之一…

SHARE 100M PRO:航测领域的多面手

在无人机航测领域&#xff0c;SHARE 100M PRO单镜头航测相机以其1.02亿像素的中画幅传感器和创新技术&#xff0c;正在重塑倾斜摄影的精度和效率。这款相机不仅在城市规划和土地管理中发挥着重要作用&#xff0c;还在环境监测、基础设施建设、农业管理等多个航测领域展现出其卓…

sheng的学习笔记-AI-多分类学习:ECOC,softmax

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 基本术语&#xff1a; 若我们欲预测的是离散值&#xff0c;例如“好瓜”“坏瓜”&#xff0c;此类学习任务称为“分类”(classification)&#xff1b; 若欲预测的是连续值&#xff0c;例如西瓜成熟度0.95、0.37&#xff0c;…

软考69-上午题-【面向对象技术2-UML】-关系

一、关系 UML中有4种关系&#xff1a; 依赖&#xff1b;关联&#xff1b;泛化&#xff1b;实现。 1-1、依赖 行为&#xff08;参数&#xff09;&#xff0c;参数就是被依赖的事物&#xff0c;即&#xff1a;独立事物。 当独立事物发生变化时&#xff0c;依赖事务行为的语义也…

js【详解】原型 vs 原型链

原型 每个 class 都有显示原型 prototype每个实例都有隐式原型_proto_实例的_proto_指向对应 class 的 prototype 如下范例&#xff1a; class Student 创建了 实例 xialuo 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时&#xff0c;先在自身属性和方法寻找&#xff0…

Visual Studio 2022 Version 17.9 新功能

Visual Studio 2022 v17.9 为广大 C 开发者引入了一系列好用的新功能和改进优化。 内存布局 现在&#xff0c;你可以使用【内存布局&#xff0c;Memory Layout】功能以可视化的方式来查看对象&#xff0c;结构体及联合体的内存布局信息&#xff0c;这可比以前需要手动查看内存…

CleanMyMac X4.15.0专为macOS设计的清理和优化工具

CleanMyMac X 是一款专为 macOS 设计的清理和优化工具。其基本功能和特点主要包括&#xff1a; 系统清理&#xff1a;CleanMyMac X 可以扫描并清除 macOS 系统中的垃圾文件&#xff0c;如缓存、日志、无用的语言文件等&#xff0c;从而释放硬盘空间并提高系统性能。应用程序管…

Tcp标志位 笔记240309

Tcp标志位 TCP&#xff08;传输控制协议&#xff09;的标志位是用于指示TCP报文段中特定控制信息的位字段。这些标志位存在于TCP报头中&#xff0c;用于控制TCP连接的建立、数据传输和终止等过程。以下是TCP标志位的详细说明&#xff1a; SYN&#xff08;同步标志&#xff09;…

python爬虫(3)

上一次的代码结果如下&#xff1a; 当然会有一点点不一样是正常的表现&#xff0c;因为这个图本身使用随机数rand函数做的&#xff0c;用其他两种随机函数出来的结果也不会完全相同。 继上节这次带来的是数组的重塑和转置 1、一维数组的重塑 在NumPy模块中的reshape()函数可…

【Vue+ElementUI】Table表格实现自定义表头展示+表头拖拽排序(附源码)

效果图 因项目采用的是Vue2&#xff0c;所以这个功能目前采用的是Vue2的写法。 Vue3请自行修改扩展代码&#xff1b;或收藏关注帖子&#xff0c;后续Vue3项目如有用到会在本帖子更新修改。 安装vuedraggable&#xff08;拖拽插件&#xff09; cnpm i vuedraggable先说用法&…

kafka查看消息两种方式(命令行和软件)+另附发送消息方式

1、命令行方式 ①找到kafka安装文件夹 ②执行命令 #指定offset为指定时间作为消息起始位置 kafka-consumer-groups.sh \ --bootstrap-server 20.2.246.116:9092 \ --group group_1 \ --topic lanxin_qiao \ --reset-offsets \ --to-datetime 2023-07-19T01:00:00.000 \ -exe…

MySQL-Linux安装

JDK安装&#xff08;linux版&#xff09; CentOS7环境&#xff1a; jdk下载地址huaweicloud.com 创建目录&#xff1a; mkdir /opt/jdk通过 ftp 客户端 上传 jdk压缩包&#xff08;linux版本&#xff09;到 1中目录进入目录&#xff1a;cd /opt/jdk解压&#xff1a;tar -zxv…

一篇了解电感的使用

一、电感理论基础 1.电感的定义 当电流通过线圈后&#xff0c;会产生磁场&#xff0c;磁感线穿过线圈&#xff0c;产生的磁通量与电流 i有如下关系&#xff1a; 将漆包线、纱包线或塑皮线等在绝缘骨架或磁心、铁心上绕制而成的器件&#xff0c;当线圈通过电流后&#xff0c;在…

linux应用程序需要编写的脚本

每一个程序都按照下面的要求进行脚本编写 多个应用之间联合安装采用编写外围脚本&#xff0c;依次调用多个应用的脚本的方式实现

MyBatis Oracle 批量插入数据

MyBatis Oracle 批量插入数据 1.需求描述2.实现方案2.1 循环 insert 插入2.2 insert all 插入2.3 insert union all 插入 3.分析总结 系统&#xff1a;Win10 JDK&#xff1a;1.8.0_351 IDEA&#xff1a;2022.3.3 1.需求描述 在一次项目中实施过程中&#xff0c;后台需要将地区…

给一篇word注音可不可以只要拼音不要汉字 word中如何只保留拼音不要汉字

word中如何只保留拼音不要汉字&#xff0c;如果你想要只保留拼音而去除汉字&#xff0c;可以通过一系列步骤来实现。以下是一个详细的教程&#xff0c;帮助你完成这个任务。 首先&#xff0c;确保你的电脑已经安装了“汇帮注音大师”软件。如果没有&#xff0c;你需要安装一下…

云计算 3月8号 (wordpress的搭建)

项目wordpress 实验目的&#xff1a; 熟悉yum和编译安装操作 锻炼关联性思维&#xff0c;便于以后做项目 nginx 编译安装 1、安装源码包 [rootlinux-server ~]# yum -y install gcc make zlib-devel pcre pcre-devel openssl-devel [rootlinux-server ~]# wget http://nginx.…

安卓7原生相机切到视频崩溃

目录 1、查看日志 2、分析日志、提取重点 3、寻找解决方法 author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 1、查看日志 由于安…

vscode setting.json 全局设置 工作区设置 位置 优先级

vscode中setting.json有两种配置权限 一、全局配置&#xff1a;setting.json文件位于C:\Users\Administrator\AppData\Roaming\Code\User\settings.json 二、工作区配置&#xff1a;setting.json文件位于工作区的.vscode\settings.json 当两种配置同时存在时&#xff0c;工作区…