lxmlxpath一站式教学
XPath定义-1010XPath是一种用于在XML文档中查找信息的语言。XPath可用于遍历XML文档中的元素和属性。它最初用于搜索XML文档,但现在也适用于搜索HTML文档。
XPath的选择功能非常强大,它提供了非常简洁清晰的路径选择表达式。此外,它还提供了100多个内置函数,用于匹配字符串、值和时间,以及处理节点和序列等。几乎任何我们想要定位的节点都可以使用XPath来选择。
pip安装lxml
读取本地html文件
etree模块将自动纠正HTML文件中缺失的内容
fromlxmlimportetree#读取html文档,字符串fp=open('index.html','r',encoding='utf-8')html=fp.read()#实例化XPath解析对象,可以转换字符串进入Element对象tree=etree.HTML(html)print(tree)
网站html文件
fromlxmlimportetreeimportrequestshtml=requests.get(url='')tree=etree.HTML(html.text)print(tree)
xpath的使用其实就是根据表达式查找文档中所有符合条件的内容。
表达式说明nodename选择该节点的所有子节点/从当前节点选择直接子节点//从当前节点选择后代节点。选择当前节点.选择当前节点的父节点@Select属性*通配符,选择具有元素名称的所有元素节点[@attrib]选择具有给定属性的所有元素[@attrib='value']选择具有给定属性和给定值[tag]选择所有指定元素的直接子节点[tag='text']选择所有指定元素且文本内容为文本节点的元素
fp=open('index.html','r',encoding='utf-8')html=fp.read()tree=etree.HTML(html)result=tree.xpath('//*')#获取所有节点print(result)
进入:
解释:
//获取当前节点的后代节点*表示匹配所有节点,//*表示获取当前节点的所有后代节点
获取后代节点中的div节点
#获取当前节点下所有div的后代节点result=tree.xpath('//div')
输出:
现在我们需要获取html下的head节点以及head节点内部的title节点。
result=tree.xpath('/html/head')#获取头节点print(result)result=tree.xpath('/html/head/title')#获取标题节点print(result)
输出:
说明:这里我们使用/来获取。每获得一个关卡,我们就依次获得目标元素。
通过/和//可以获取子节点或后代节点。现在学习如何通过子节点找到父节点。
查找li节点的父节点,查找li节点的父节点的父节点
result=tree.xpath('//li/.')print(结果)result=tree.xpath('//li/./.')print(结果)
输出:
通过输出我们可以看到li的父节点是ul,ul的父节点是div。
解释:
先通过//li找到li节点,然后通过.找到父节点
查找li标签中class=item01的元素
结果=tree.xpath('/html/body/div/ul/li[@class='item01']')print(结果)
输出:
选择具有id的属性
结果=tree.xpath('/html/body/div/ul/li[@id]')print(结果)
输出:
解释:
通过@我们可以根据属性查找节点,指定属性值,或者直接根据属性查询。
获取li中的文本
#直接获取li标签下所有后代元素的文本result=tree.xpath('/html/body/div/ul/li//text()')print(result)#通过查找子元素,一级一次Level找到文本result2=tree.xpath('/html/body/div/ul/li/a/text()')print(result2)
输出:
通过对输出内容的分析,我们可以看到直接通过li//text()获取更多的文本内容会比li/a/text()获取更多的文本内容,因为li//text()还是获取所有的文本li中包含换行符,li/a/text()只会查找a标签下的所有文本
有时我们在解析数据时需要一些属性值。比如我们写爬虫项目的时候,经常需要url链接。
查找li中id=id01a标签中href的值
结果=tree.xpath('/html/body/div/ul/li[@id='id01']/a/@href')print(结果)
输出
解释:
获取属性值也是通过@来实现,@href:获取href的属性值
在实际项目中,一个属性值可能有多个值。例如,实际项目中一个类可能有多个值。
获取class中包含class_val1的节点
#这种方法是错误的,不会在对应的类树中找到包含class_val1的节点。xpath('/html/body/div/ul/li[@class='class_val1']')#正确的做法使用contains()function#获取类中包含class_val1的节点result=tree.xpath('/html/body/div/ul/li[contains(@class,'class_val1')]')print(result)
输出:
解释:
contains()函数获取指定属性中包含某个属性值的节点。
用法contains(@property,'属性值')
有时我需要根据多个属性确定一个节点
查找li中a标签中class中包含item01且id=id01的文本
结果=tree.xpath('/html/body/div/ul/li[包含(@class,'item01')和@id='id01']/a/text()')print(结果)
解释:
使用and连接多个条件值
扩展类似的运算符也是
运算符说明实例返回值or或age=10或age=20如果age等于10或等于20,则返回true。无论如何,返回falseand以及age19和age21。如果年龄等于20,则返回true,否则返回falsemodmodulus5mod21|取两个节点的集合//book|//cd返回包含book和cd元素的所有节点的集合+加5+49-减5-41*乘5*420div除6div32=等于age=10true!=不等于age!=10true小于age10true=小于等于age=10true大于age10true=大于等于age=10true
有时我们在选择时可能会匹配到多个节点,但我们可能只需要其中的一些节点,xpath为我们提供了操作可以根据索引取值。
注意xpath中的索引是从1开始的,不是从0开始的
获取第一个li标签
获取前三个li标签
获取最后一个li标签
#获取第一个`li`标签result=tree.xpath('/html/body/div/ul/li[1]')print(result)#获取前三个`li`标签result2=tree.xpath('/html/body/div/ul/li[position()4]')print(result2)#获取最后一个`li`标签result3=tree.xpath('/html/body/div/ul/li[last()]')打印(结果3)
输出:
解释:
position()返回当前正在处理的节点的索引位置
last()返回所有匹配节点的最后一个索引
Axis定义相对于当前节点的一组节点。
获取li的所有祖先节点
结果=tree.xpath('/html/body/div/ul/li/ancestor:*')print(结果)
输出:
获取li祖先节点中的div
结果=tree.xpath('/html/body/div/ul/li/ancestor:div')print(结果)
输出:
获取li节点的后代元素
结果=tree.xpath('/html/body/div/ul/li/child:*')print(结果)
获取li节点的后代元素中a标签中的href='./index.html'
结果=tree.xpath('/html/body/div/ul/li/child:a[@href='./index.html']')print(结果)
解释:
祖先和孩子都称为轴祖先。轴是相对于当前节点的所有祖先节点的集合。子轴是相对于当前节点的后代节点集合,后面是对该轴节点集合的操作。*表示匹配所有节点。div表示节点集中的div节点,
另外,还可以使用其他过滤条件过滤child:a[@href='./index.html']:选择后代节点的a节点中href='./index.html'的节点。上面学到的过滤方法都可以使用。在这里使用。
像这样的轴还有很多
轴名称结果Ancestor选择当前节点的所有祖先。ancestor-or-self选择当前节点的所有祖先以及当前节点本身。attribute选择当前节点的所有属性。child选择当前节点的所有子元素。Descendant选择当前节点的所有后代元素。Descendant-or-self选择当前节点的所有后代元素以及当前节点本身。以下选择文档中当前节点的结束标记之后的所有节点。namespace选择当前节点的所有命名空间节点。Parent选择当前节点的父节点。pceding选择文档中当前节点开始标记之前的所有节点。pceding-sibling选择当前节点之前的所有兄弟节点。self选择当前节点。xpath轴的使用方式相同。实际中我们只需根据自己的需要选择合适的轴即可。
关于lxml和xpath的教导大概有很多。这些教程中的许多用法并不容易解释。这里只是一些用法。如果你想熟练使用xpath解析数据,就需要经常练习,并结合自己的实际情况。根据情况选择具体的xpath,
使用一段时间后,你可能会发现最常用的就是获取子节点、获取后代节点、获取文本、获取属性值。这些足以解决你遇到的大部分问题。以下有关xpath轴的内容可能实际上在您考虑之前就解决了问题。但我还是建议你学习一下。当我们看别人的代码时,别人可能会用到它。平时我们可能不会写,但是看到这样的代码我们一定能认出来。
【前端灵魂脚本语言JavaScript】——JS中数组的使用作者:阿伟个人主页:Flymeawei希望大家支持我们,共同进步!文章对您有帮助,关注点赞收藏Jav…
在Vue中,父组件的异步数据通过props传递给子组件,但子组件无法接收。vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题问题描述在基…
Java如何解析html中的内容并保存到数据库一、前言最近接到一个任务,需要爬取五级行政区划的所有数据,以及需要抓取的网站爬取了:行政区划-行政区划代码查询发现…
有些系统文件夹无法打开,并显示“您被拒绝访问此文件夹”的消息,这有点令人困惑。显然我是管理员帐户,整台电脑都是我的。你怎么能.某些系统文件文件夹无法打开,并显示…
如何免费获取Windows10激活密钥?Windows10系统需要激活才能使用所有功能。一般来说,想要激活win10系统,需要去官网购买激活码。不过也有一些激活…
2024-05-02 16:15:46
2024-05-02 16:06:29
2024-05-02 15:49:51
2024-05-02 15:33:05
2024-05-02 15:17:14
Win10蓝牙鼠标已连接但无响应怎么办?使用Win10电脑时,发现蓝牙鼠标已连接…
本篇文章给大家谈谈附近学电脑培训中心宝鸡,以及宝鸡电脑培训班对应的知识点,希望对…