python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解
目录
一、 etree 介绍
lxml
库是 Python 中一个强大的 XML 处理库,简单来说,etree 模块提供了一个简单而灵活的API来解析和操作 XML/HTML 文档。
- 官方网址:The lxml.etree Tutorial
- 安装:pip install lxml
二、xpath 解析 html/xml
1、第一步就是使用 etree 连接 html/xml 代码/文件。
语法:
- root = etree.XML(xml代码) #xml 接入
- root = etree.HTML(html代码) #html 接入
- 引入 from lxml import etree
from lxml import etree
root = etree.XML("data")
print(root.tag)
#root
print(etree.tostring(root))
#b'data'
root = etree.HTML("data")
print(root.tag)
#html
print(etree.tostring(root))
#b'data'
2、 xpath 表达式定位
xpath 使用路径表达式在 HTML/XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式:
表达式 | 描述 |
---|---|
/ | 从根节点选取(取子节点) |
// | 任意节点,不考虑位置(取子孙节点) |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
contain(@属性,“包含的内容”) | 模糊查询 |
text() | 文本内容 |
① xpath结合属性定位
- html.xpath(“.//标签名[@属性=‘属性值’]”) #注意,这返回的是列表!!
- [] :表示要根据属性找元素
- @ :后边跟属性的key,表示要通过哪个属性定位
from lxml import etree
ht = """
This is a sample document
Hello!
This is a paragraph with bold text in it!
This is another paragraph, with a
link.
Here are some reserved characters: <spam&egg>.
And finally an embedded XHTML fragment.
"""
html = etree.HTML(ht)
title = html.xpath(".//h1[@class='title']")[0] #取列表中的第一个元素
print(etree.tostring(title))
#b'Hello!\n '
print(title.get('class'))
# title
② xpath文本定位及获取
- ele = html.xpath(“.//标签名[text()=‘文本值’]”)[0]
- text1 = ele.text #获取元素文本1,ele为定位后的元素
- text2 = html.xpath(“string(.//标签名[@属性=‘属性值’])”) #获取元素文本2,返回文本
- text3 = html.xpath(“.//标签名[@属性=‘属性值’]/text()”) #获取元素文本3,返回文本列表
title1 = html.xpath(".//h1[text()='Hello!']")[0] #取列表中的第一个元素
text1 = title1.text
print(text1)
#Hello!
text2 = html.xpath("string(.//h1[@class='title'])")
print(text2)
#Hello!
text3 = html.xpath(".//h1[@class='title']/text()") #返回列表
print(text3)
#['Hello!']
③ xpath层级定位
实际开发时,若需求元素没有像 id、name、class 等基本属性,那么我们就需要借助相邻的元素定位,首先我们可以定位到相邻元素,然后通过层级关系来定位最终元素。
- html.xpath(“.//父元素标签名[@父元素属性=‘父元素属性值’]/子元素标签名”) #由上到下的层级关系,目标是子元素
- html.xpath(“.//子元素标签名[@子元素属性=‘子元素属性值’]/parent::父元素标签名”) #父子元素定位,目标是父元素
在这里插入代码片
- html.xpath(“.//元素标签名[@元素属性=‘元素属性值’]//preceding-sibling::哥哥元素标签名”) #哥哥元素定位,目标是哥哥元素
- html.xpath(“.//元素标签名[@元素属性=‘元素属性值’]//following-sibling::弟弟元素标签名”) #弟弟元素定位,目标是弟弟元素
from lxml import etree
ht = """
This is a sample document
Hello!
This is a paragraph with bold text in it!
This is another paragraph, with a
link.
Here are some reserved characters: <spam&egg>.
And finally an embedded XHTML fragment.
"""
html = etree.HTML(ht)
ele1 = html.xpath(".//p[@class='para']/a")[0] #由上到下的层级关系
print(etree.tostring(ele1))
#b'link.'
ele2 = html.xpath(".//a[@href='http://www.python.org']/parent::p")[0]#父子元素定位
print(etree.tostring(ele2))
#b'This is another paragraph, with a\n link.\n '
ele3 = html.xpath(".//p[@class='para']//preceding-sibling::p")[0] #哥哥元素定位
print(etree.tostring(ele3))
#b'This is a paragraph with bold text in it!\n '
ele4 = html.xpath(".//p[@class='para']//following-sibling::p") #弟弟元素定位
for ele in ele4:
print(etree.tostring(ele))
#b'Here are some reserved characters: <spam&egg>.\n '
#b'And finally an embedded XHTML fragment.\n '
④ xpath索引定位
etree 结合 xpath 进行索引定位主要有两种方式,主要是因为 html.xpath() 返回的是一个列表。
- html.xpath(“xpath表达式”)[0] #获取列表中第一个元素
- html.xpath(“xpath表达式”)[-1] #获取列表中最后一个元素
- html.xpath(“xpath表达式”)[-2] #获取列表中倒数第二个元素
ele1 = html.xpath(".//body/p")[0]
print(etree.tostring(ele1))
#b'This is a paragraph with bold text in it!\n '
ele1 = html.xpath(".//body/p")[-1]
print(etree.tostring(ele1))
#b'And finally an embedded XHTML fragment.\n '
语法2:
html.xpath(“xpath表达式[1]”)[0] #获取第一个元素
html.xpath(“xpath表达式[last()]”)[0] #获取最后一个元素
html.xpath(“xpath表达式[last()-1]”)[0] #获取倒数第二个元素
注:与python列表索引的概念不同,xpath 的标签索引是从1开始;python列表的索引是从0开始。
⑤ xpath模糊匹配
有时会遇到属性值过长的情况,此时我们可以通过模糊匹配来处理,只需要属性值的部分内容即可。
html.xpath(“.//标签名[start-with(@属性, ‘属性值开头’)]”) #匹配开头
html.xpath(“.//标签名[ends-with(@属性, ‘属性值结尾’)]”) #匹配结尾
html.xpath(“.//标签名[contains(text(), ‘部分文本’)]”) #包含部分文本
注:ends-with方法是 xpath 2.0 的语法,而 etree 只支持 xpth 1.0,所以可能不会成功。
ele1 = html.xpath(".//p[starts-with(@class,'par')]")[0] #匹配开头
print(etree.tostring(ele1))
#b'This is another paragraph, with a\n link.\n '
ele2 = html.xpath(".//p[ends-with(@class, 'ara')]")[0] #匹配结尾
print(etree.tostring(ele2))
ele3 = html.xpath(".//p[contains(text(),'is a paragraph with')]")[0] #包含“is a paragraph with”
print(etree.tostring(ele3))
#b'This is a paragraph with bold text in it!\n '
python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解python中lxml 库之 etree 使用详解 python中lxml 库之 etree 使用详解