首页IT科技python如何提取网页中数据(Python3爬虫——用Xpath提取网页信息)

python如何提取网页中数据(Python3爬虫——用Xpath提取网页信息)

时间2025-06-20 02:46:47分类IT科技浏览4385
导读:Python3爬虫——用Xpath提取网页信息 前言...

Python3爬虫——用Xpath提取网页信息

前言

本笔记用于记录整理requests库的一些基本知识            ,内容会根据博主自己的认知作增添或压缩            。

水平有限                  ,如有错误请不吝赐教                 。

本文需要读者初步了解HTML有关节点的相关知识      。

Xpath的梗概和安装

XPath即为XML路径语言(XML Path Language)     ,它是一种用来确定XML文档中某部分位置的语言         。XPath基于XML的树状结构         ,提供在数据结构树中找寻节点的能力                 。使用Xpath最初是用于搜寻XML文档的                  ,但同样适用于HTML文档的搜索         。

使用Xpath前        ,请先保证其已经安装      ,可以利用pip进行安装:

pip3 install lxml

这里主要用到lxml包内的etree的库                  ,其提供了Xpath的方法      。

Xpath常用规则

表达式 描述 nodename 选取此节点的所有子节点 / 进入当前节点的直接子节点 // 进入当前节点的子孙节点 . 选取当前节点 .. 选取当前节点的父节点 @ 选取当前节点的属性

小试牛刀:

//title[@endtime="2023-02-04"]

意思是选取所有名为title并带有属性endtime为"2023-02-04"的节点

使用Xpath

接入HTML文本

从内存中读取

假设已经存在这样一段HTML文本:

text = <div class="device-notification"> <a class="device-notification--logo" href="#0"> <img src="assets/img/logo.png" alt="Global"> <p>Emoreの云</p> </a> <p class="device-notification--message">请将手机横向放置以继续体验</p> </div>

这意味着这段HTML存在内存内           ,可能是网上抓取来的或是提前读取好的   ,接入Xpath的方法如下:

import lxml import etree # 载入etree库 html = etree.HTML(text) # 构造Xpath解析对象 从文件中读取

假设有一个text.html文件在你的程序所在的文件夹中                  ,里面这需要解析的HTML文本:

from lxml import etree # 载入etree库 html = etree.parse(./text.html, etree.HTMLParser()) # 从文本构造Xpath解析对象

不论是哪种方法构造Xpath解析对象              ,etree都会对HTML文本进行修正                 。如果从文件读取,修正时可能额外出现DOCTYPE声明            。

查找节点

所有节点

利用Xpath查找结点时               ,一般采用以//开头的Xpath规则选择所有符合要求的节点   。以上文的HTML文本为例:

>>> html = etree.HTML(text) >>> result1 = html.xpath(//*) # *代表选择当前目录的所有节点 >>> print(result1) # 返回结果是列表 [<Element html at 0x27378d2c440>, <Element body at 0x27378e98140>, <Element div at 0x27378e98300>, <Element a at 0x27378e98400>, <Element img at 0x27378e98440>, <Element p at 0x27378e98480>, <Element p at 0x27378e98240>] >>> print(result1[0]) # 选取结果中的第一个 <Element html at 0x27378d2c440>

其中Element后面的内容便是节点名                 ,本身不存在的html节点和body节点都自动补全了                 。

指定节点

将//后面的内容换成节点名  ,即可查找指定节点            ,如查询上文所有的p节点:

>>> result2 = html.xpath(//p) >>> print(result2) [<Element p at 0x27378e98480>, <Element p at 0x27378e98240>]

同时可以查询具有指定属性的p节点                  ,只需要在节点名后面附带筛选属性     ,利用[@]将其包裹起来:

>>> result3 = html.xpath(//p[@class="device-notification--message"]) >>> print(result3) [<Element p at 0x27378e98240>]

如此只返回了最后一个p节点               。

属性多值匹配

有的属性不止有一个值(上文HTML并没有这种情况)         ,需要用contains()方法进行匹配。该方法第一个参数为属性名                  ,第二个参数填入属性值        ,只要拥有该属性值的节点都会被返回              。

result = html.xpath(//p[contains(@class, "device-notification--message")]) 多属性匹配

需要通过多个属性匹配一个节点      ,可以利用and进行连接                  ,比如匹配一个class含有值device并且name为Emore的p节点:

result = html.xpath(//p[contains(@class, "device") and @name="Emore"]) # 仅举例

除了and           ,Xpath还含有很多运算符(摘自菜鸟编程)   ,

运算符 描述 实例 返回值 | 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集 + 加法 6 + 4 10 - 减法 6 - 4 2 * 乘法 6 * 4 24 div 除法 8 div 4 2 = 等于 price=9.80 如果 price 是 9.80                  ,则返回 true                 。如果 price 是 9.90              ,则返回 false   。 != 不等于 price!=9.80 如果 price 是 9.90,则返回 true            。如果 price 是 9.80               ,则返回 false                 。 < 小于 price<9.80 如果 price 是 9.00                 ,则返回 true      。如果 price 是 9.90  ,则返回 false         。 <= 小于或等于 price<=9.80 如果 price 是 9.00            ,则返回 true                 。如果 price 是 9.90                  ,则返回 false         。 > 大于 price>9.80 如果 price 是 9.90     ,则返回 true      。如果 price 是 9.80         ,则返回 false                 。 >= 大于或等于 price>=9.80 如果 price 是 9.90                  ,则返回 true            。如果 price 是 9.70        ,则返回 false   。 or 或 price=9.80 or price=9.70 如果 price 是 9.80      ,则返回 true                 。如果 price 是 9.50                  ,则返回 false               。 and 与 price>9.00 and price<9.90 如果 price 是 9.80           ,则返回 true。如果 price 是 8.50   ,则返回 false              。 mod 计算除法的余数 5 mod 2 1 选择顺序

有时候有两个或者多个节点                  ,可以像列表一样选择其中某个节点                 。需要注意的是              ,Xpath是从1开始计数的   。

# 仅举例 result = html.xpath(//div/p[0]) # 选择第一个p节点 result = html.xpath(//div/p[last()]) # 选择最后一个p节点 result = html.xpath(//div/p[posision()<3]) # 选择前面两个p节点 result = html.xpath(//div/p[last()-2]) # 选择倒数第三个p节点 查找子孙节点

查找子孙节点只需要像文件路径一样/下去就好了,不同的是/是只访问直接子节点               ,而//是访问所有的子孙节点:

例如我需要寻找div节点下的p节点:

>>> result4 = html.xpath(//div/p) # 利用/搜索节点p >>> result5 = html.xpath(//div//p) # 利用//搜索节点p >>> print(result4) [<Element p at 0x27378e98240>] >>> print(result5) [<Element p at 0x27378e98480>, <Element p at 0x27378e98240>]

div节点的直接子节点中含有一个p节点                 ,还有一个a节点            。其中a节点内含有一个img节点和一个p节点                 。利用/只检索到一个p节点  ,而利用//检索到了两个p节点            ,即访问了子节点和孙节点      。

查找父节点

同样类似命令cd ..打开上级目录                  ,Xpath中的..可以用于进入父节点         。

>>> result6 = html.xpath(//div/p/../a/img) >>> print(result6) [<Element img at 0x27378e98440>]

首先进入了div节点的p节点     ,然后从p节点返回绕到了a节点         ,并取得里面的img节点                 。

获得属性和文本

利用Xpath内的text()方法可以获得节点的文本                  ,利用@可以获得指定属性的值         。

>>> print(result7) [请将手机横向放置以继续体验] >>> result8 = html.xpath(//div/p/@class) >>> print(result8) [device-notification--message]

同样输出为列表      。

节点轴选择

通过轴节点可以快速选择具有相关关系的节点        ,如选择div节点的所有直接子节点:

>>> result10 = html.xpath(//div/child::*) >>> print(result10) [<Element a at 0x27378e98400>, <Element p at 0x27378e98240>]

首先需要调用child轴      ,获得所有匹配的节点                  ,然后使用两个冒号::进入选择器           ,接着用*选择所有节点                 。

还有很多轴可供选择(摘自菜鸟编程):

轴名称 结果 ancestor 选取当前节点的所有先辈(父            、祖父等)            。 ancestor-or-self 选取当前节点的所有先辈(父                  、祖父等)以及当前节点本身   。 attribute 选取当前节点的所有属性                 。 child 选取当前节点的所有子元素               。 descendant 选取当前节点的所有后代元素(子     、孙等)。 descendant-or-self 选取当前节点的所有后代元素(子         、孙等)以及当前节点本身              。 following 选取文档中当前节点的结束标签之后的所有节点                 。 following-sibling 选取当前节点之后的所有兄弟节点 namespace 选取当前节点的所有命名空间节点   。 parent 选取当前节点的父节点            。 preceding 选取文档中当前节点的开始标签之前的所有节点                 。 preceding-sibling 选取当前节点之前的所有同级节点      。 self 选取当前节点         。

小结

使用XPath可以快速而准确地进行HTML节点选择   ,并提取信息                  ,但是要注意构造XPath表达式              ,以避免提取错误                 。

同时还有一些需要注意的地方:

顺序选择节点时,起始数为1 选择文本的时候需要精准地进入节点               ,否则text()会返回错误的文本                 ,如一个换行符或一个缩进         。
声明:本站所有文章  ,如无特殊说明或标注            ,均为本站原创发布      。任何个人或组织                  ,在未征得本站同意时     ,禁止复制                  、盗用        、采集      、发布本站内容到任何网站                  、书籍等各类媒体平台                 。如若本站内容侵犯了原著者的合法权益         ,可联系我们进行处理            。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
微信投票钱到哪去了(微信投票如何提现-又有平台顶风作案!无法提现已成常态?) 武汉安全员证报考条件2020考试时间表(2023年武汉安全员C证报考条件、流程、报名时间是什么?启程别)