XPath 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历,快速提取xml文档中的的信息,详细的xpath教程参见:https://www.w3school.com.cn/xpath/index.asp。
xpath用法
//任意层次下,/ 根或下一层
//@id
任意层次下有id的节点的属性值
//*[@id] //book[@id]
所有含有id属性的节点 含有id属性的book节点
/bookstore/* /bookstore//*
一层的所有节点 递归下去每一层节点
//* //@* // *[@*]
*表示所有,@是取属性值
//book[position()=3] //book[positon()
限制book节点的位置范围
//book[price>400]
price是子节点,其值大于40的book节点
/book/text() /book//text()
下的所有文本节点,/子节点和 // 子孙节点
//*[local-name()="book"]
所有节点中名称为book的
//book/child::node()
node()表示节点,child::表示子节点
//*[self::title or self::price]
任意层次下的节点,这些节点自身是title或者price
//book[contains(@class, class_name)]
contains() 包含,class属性中包含class_name的节点
//*[contains(local-name(), book)]
标签名包含book的节点
其他还提供了如local-name()等函数,可查看w3cSchool获取详细用法。
lxml
它是python的一个库,用于对xml和html文档进行解析,性能非常好,最新版支持的2.6+,python3支持到3.6。
centos安装
在centos下需要编译安装两个依赖:libxml2-devel 和 libxslt-devel
依赖安装完成后,使用pip安装即可
lxml的使用
lxml是使用C语言的开发的对xml及html文本的解析库,主要基于C语言的计算速度快的有点,python的lxml只是封装了调用接口,方便python使用lxml解析xml文本。
etree.HTML
from lxml importetree
html_text= """
"""
#我们获取的一个网页的html文本数据,字符串或者字节序列均可,
root= etree.HTML(html_text) #返回一个root节点对象,相当于html的document全局根对象
print(root, type(root)) #
也可以通过fromstring方法解析,获取根_Element对象。获取root对象后,可以通过root对象找到其所有的子节点也就是html中的所有子标签。常用的方式就是通过xpath语法解析及即可。如果我们直接读取一个html文件中的html 内容,使用html=etree.parse('test.html',etree.HTMLParser())的方式即可,同时会自动修复html中的一些标签的问题。每一个_Element元素对象中都包含了其直接子_Element,使用容器化的方式关联了直接子_Element,例如在div标签下有一个直接子标签ul。我们可以通过xpath的解析方式去获得div的_Element对象。
div_element = root.xpath("//div") #任意层次下的ul标签,只有一个
print(div_element) #
print(len(div_element)) #1,长度为一,只有一个ul子标签
ul_element = div_element[0] #容器的方式直接取第一个子标签,及ul标签
#也可直接对其进行遍历
for li inul_element:print(li) #3个li对应的_Element对象
etree._Element
每一个_Element对象对应了html中的标签,类似于一棵DOM树的结构,我们可以手动创建单个节点,并可以将多个_Element合并到这个dom 树上的指定位置,与的其他_Element对象产生关系。
每一个_Element对象的操作方式和jQuery的对dom树中节点的操作极其相似。
from lxml.etree import Element #Element是一个工厂函数,返回一个指定名的_Element对象
root= Element("root", attrib={"abc":"hello"}, id="2123") #两种方式添加属性,
print(etree.tostring(root, pretty_print=True)) #tostring函数打印节点源码 b''
print(root.tag) #标签名 root
属性值得创建可以通过attrib参数来指定,也可以使用关键字传参得方式指定,未定义得关键字都将收集到**extra可变关键字参数中,与attrib字典值合并作为属性。_Element通过字典得方式管理属性一个标签的属性信息,并提供了访问接口
print(etree.tostring(root)) #tostring函数打印节点源码 b''
root.get("id") #获取一个属性值,2123
root.set("name", "title") #添加一个属性,name=title
两个_Element对象之间可以建立关系,可以成为兄弟节点(同级)和父子节点得关系。
root = Element("root") #
body = Element("body") #