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,浏览器一般会自动渲染上。
解决方法:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫入门到精通_实战篇10(使用Redis+Flask维护动态代理池)

1 目标 为什么要用代理池 许多网站有专门的反爬虫措施&#xff0c;可能遇到封IP等问题。互联网上公开了大量免费代理&#xff0c;利用好资源。通过定时的检测维护同样可以得到多个可用代理。 代理池的要求 多站抓取&#xff0c;异步检测定时筛选&#xff0c;持续更新提供接…

12 状态优先级

概念 cpu需要执行很多进程&#xff0c;有很多进程排在队列中&#xff0c;每个进程加载后运行一定的时间段&#xff0c;然后切换下一个进程。cpu如何判断进程需不需要加载&#xff0c;什么时候加载&#xff0c;依靠进程的状态和优先级属性来判断&#xff0c;进程调度&#xff0…

Gitlab: PHP项目CI/CD实践

目录 1 说明 2 CI/CD 2.1 部署方式一&#xff1a;增量部署 2.1.1 目标服务器准备 2.2.2 Gitlab及Envoy脚本 2.2 部署方式二&#xff1a;镜像构建与部署 2.2.1 推送到私有化容器仓库 准备工作 脚本 要点 2.2.2 推送到hub.docker.com 准备工作 脚本 3 参考&#x…

深入探讨 AutoGPT:彻底改变游戏的自主 AI

原文地址&#xff1a;Deep Dive into AutoGPT: The Autonomous AI Revolutionizing the Game 2023 年 4 月 24 日 AutoGPT 是一个功能强大的工具&#xff0c;它通过 API 使用 GPT-4 和 GPT-3.5&#xff0c;通过将项目分解为子任务并在自动循环中使用互联网和其他工具来创建完…

力扣hot8---滑动窗口

这里先跳过力扣hot7啦&#xff0c;这几天就回更~ 题目&#xff1a; 滑动窗口思路&#xff1a; 首先左窗口&#xff08;left&#xff09;指向的是第0个元素&#xff0c;依次遍历循环每一个元素&#xff0c;维护一个unordered_set&#xff0c;如果当前被遍历的元素存在于unorder…

Python实现ADTM工具判断信号:股票技术分析的工具系列(6)

Python实现ADTM工具判断信号&#xff1a;股票技术分析的工具系列&#xff08;6&#xff09; 介绍算法解释 代码rolling函数介绍完整代码data代码ADTM.py 介绍 ADTM&#xff08;动态买卖气指标&#xff09;是一种用于衡量市场买卖力量对比的指标。它通过计算动态买盘指标&#…

【源码】imx6ull实现触摸屏单点实验-移植tslib和qt

一、本实验实验的器材&#xff1a; 1.正点原子imx6ull的阿尔法开发板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、实验已经移植好的文件&#xff1a; 仓库代码&#xff1a;https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件说明 arm-qt.tar.bz2&#xff1a;移植好的…

tsc : 无法加载文件 C:\Users\Administrat\AppData\Roaming\npm\tsc.ps 1,因为在此系统上禁止运行脚本

报错&#xff1a;tsc : 无法加载文件 C:\Users\Administrat\AppData\Roaming\npm\tsc.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 解决 使用命令行时出现ab…

idea中引入新JDK环境

在不同的项目中往往会需要不同的运行环境&#xff0c;那么如何下载一个新的环境并运用到idea中呢&#xff1f; 下面给出的就是oracle官网&#xff0c;以JDK17为例教大家如何下载 Java Archive Downloads - GraalVM for JDK 17https://www.oracle.com/java/technologies/javase…

世界的本质是旋转(5)-在复平面上驱动软件无线电SDR发射BPSK波形

在上一篇文章中&#xff0c;我们介绍了复平面、拍照采样的一些思维实验。从本节开始&#xff0c;转入现实应用&#xff0c;通过控制复平面向量的位置&#xff0c;实现一个完整的BPSK全双工通信通道。 发射方&#xff1a;通过控制复平面向量在各个时刻的位置来携带信息的技术&a…

108. 将有序数组转换为二叉搜索树【简单】

108. 将有序数组转换为二叉搜索树【简单】 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉…

电脑不小心格式化了,怎么恢复?

在这个数字化时代&#xff0c;电脑已经成为我们日常生活和工作中不可或缺的工具。然而&#xff0c;有时我们可能会不小心格式化电脑硬盘&#xff0c;导致重要数据的丢失。那么&#xff0c;电脑不小心格式化了&#xff0c;怎么恢复&#xff1f; 别着急&#xff0c;在本篇攻略中&…

vue3页面内容切换(类似登录、注册内容切换)

一、内容描述 页面有俩块内容&#xff0c;分别是验证码登录页面内容&#xff0c;账号密码登录页面内容。有俩种处理方式&#xff0c;一个是写俩个页面跳转使用&#xff0c;还有一种是一个页面俩个内容&#xff0c;切换的只是不同的内容&#xff0c;相同的内容保留。一般都是选择…

音视频开发之旅——音频基础概念、交叉编译原理和实践(LAME的交叉编译)(Android)

本文主要讲解的是音频基础概念、交叉编译原理和实践&#xff08;LAME的交叉编译&#xff09;&#xff0c;是基于Android平台&#xff0c;示例代码如下所示&#xff1a; AndroidAudioDemo 音频基础概念 在进行音频开发的之前&#xff0c;了解声学的基础还是很有必要的。 声音…

Windows安装SSH教程

Windows安装SSH教程 一、SSH1.SSH简介2.SSH功能3.SSH验证3.1 第一种级别&#xff08;基于口令的安全验证&#xff09;3.2 第二种级别&#xff08;基于密匙的安全验证&#xff09; 4.SSH层次4.1 传输层协议 [SSH-TRANS]4.2 用户认证协议 [SSH-USERAUTH]4.3 连接协议 [SSH-CONNEC…

改造muduo,不依赖boost,用C++11重构

组件的实现 1. 序 1.1. 总述 muduo库是基于多Reactor-多线程模型实现的TCP网络编程库&#xff0c;性能良好。如libev作者&#xff1a;“One loop per thread is usually a good model”&#xff0c;muduo库的作者陈硕在其《Linux多线程服务端编程》中也力荐这种“One loop pe…

linux中对信号的认识

信号的概念与相关知识认识 信号是向目标进程发送消息通知的的一种机制。 信号可以以异步的方式发送给进程&#xff0c;也就是说&#xff0c;进程无需主动等待&#xff0c;而是在任何时间都可以接收到信号。 信号的种类 用kill-l命令查看系统定义的信号列表&#xff1a; 前台…

初识Hive

官网地址为&#xff1a; Design - Apache Hive - Apache Software Foundation 一、架构 先来看下官网给的图&#xff1a; 图上显示了Hive的主要组件及其与Hadoop的交互。Hive的主要组件有&#xff1a; UI&#xff1a; 用户向系统提交查询和其他操作的用户界面。截至2011年&…

Linux - 安装 maven(详细教程)

目录 一、下载二、安装三、配置环境变量四、镜像资源配置 一、下载 官网&#xff1a;https://maven.apache.org/download.cgi 打开 maven 的官网下载页面&#xff0c;点击 bin.tar.gz 文件链接 即可下载最新版本的 maven 如果想要下载旧版本的 meven&#xff0c;则点击 Maven…

【短时交通流量预测】基于GRNN神经网络

课题名称&#xff1a;基于GRNN神经网络的短时交通流量预测 版本时间&#xff1a;2023-04-27 代码获取方式&#xff1a;QQ&#xff1a;491052175 或者 私聊博主获取 模型简介&#xff1a; 城市交通路网中交通路段上某时刻的交通流量与本路段前几个时段的交通流量有关&#x…