0301lxml
lxml 是 Python 的一个解析库,支持 HTML 和 XML 的解析,支持 XPath 解析方式(xml 是一个非常重要的库,比如 BeautifulSoup、Scrapy 框架都需要用到此库)
网页数据的解析提取(p90)
XML 路径语言(XML path language)
用来在XML文档中查找信息,同样适用HTML文档的搜索
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
* | 任意元素 |
*@ | 任意属性 |
1
//title[@lang='eng'] #选择所有名称(nodename)为 tilte, 属性 lang='eng'的节点
安装:
pip3 install lxml
使用
例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from lxml import etree
text="""<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-inactive"><a href="link2.html">second item</a></li>
<li class="item-2"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0" name="it4"><a href="link5.html">fifth item</a></li>
</ul>
</div>
"""
html=etree.HTML(text)
print( html.xpath('//*') ) #1选取所有子节点选取所有子节点
print( html.xpath('//li/a') ) #2选取子节点选选取所有 li 节点下的 直接节点a。 如果改成://ul/a 则返回[]
print( html.xpath('//a[@href="link4.html"]/../@class') ) #3选取父节点查找子孙节点a,属性href="link4.html,的父节点,获取该父节点的class值
#4 ..=parent::*,上句等价于://a[@href="link4.html"]/parent::*/@class
print( html.xpath('//li[@class="item-0"]/a/text()') ) #5文本获取text():获取节点 li,属性 class="item-0"",的所有直接子节点 a的 文本
print( html.xpath('//li[@class="item-0"]//text()') ) # 获取节点 li,属性 class="item-0"",的所有子节点的 文本
print( html.xpath('//li/a/@href')) #6获取属性
##7属性包含(contain)匹配
print( html.xpath('//li[contains(@class,"-inactive")]/a/text()') ) #返回['second item']
属性操作符:
通过and、or
等操作可以组合多个属性选择(p96)
运算符 | 描述 | 实例 |
---|---|---|
and、or | 与、或 | //li[contains(@class,”-0”) and @name=”it4” ]/a/text(),返回 fifth item |
mod | 取莫 | //li[position() mod 2=0 ]/a/text(),返回[‘second item’, ‘fourth item’] |
| | 多个路径(或)计算两个节点集 | //li[@class=”item-inactive”]/a/text() | //li[@class=”item-1”]/a/text(),返回[‘second item’, ‘fourth item’] |
+、-、*、div | 加、减、乘、除 | |
=、!= | 等于、不等于 | |
<、>、<=、>= | 小于、大于、小于等于、大于等于 | html.xpath(“//li[position() < 3]/a/text()”) |
节点按序选择
1
2
3
4
5
#注意节点是从1开始!!不是从0开始的
#1.position()、last():获取节点 当前、最后一个序号
print( html.xpath('//li[1]/a/text()'))
print( html.xpath('//li[first()]/a/text()'嗯))
print( html.xpath('//li[position()<3]/a/text()'))
节点轴选择(p97)
操作符 | 描述 | 例子 |
---|---|---|
text() | 获取文本 | li[@class=”item-inactive”]/a/text() |
parent | 获取父节点 | //a[@href=”link4.html”]/parent::*/@class |
ancestor | 获取所有祖先节点 | //li[1]/ancestor::*‘,返回 html、body、div、ul节点 |
descendant | 获取所有子孙节点 | //ul/descendant::li[1]/a/text()’,返回[‘first item’] //ul/descendant::li[@class=”item-inactive”]/a/text()’,返回[‘second item’] |
child | 获取所有直接子节点 | //ul/child::*[1]/a/text(),返回[‘first item’] |
attribute | 获取所有属性 | //li[last()]/attribute::*,返回[‘item-0’, ‘it4’] |
following | 获取当前节点之后的所有节点 | //li[1]/following::*[2]/@href,返回[‘link2.html’](注意following会将嵌套的子节点和父节点平铺。比如<li><a><\/a><\/li>:li是第一个节点而a是第二个节点) |
following-sibling | 获取当前节点之后的所有同级节点 | //li[1]/following-sibling::*,返回后面四个 li 节点 |
contains | 包含 | html.xpath(‘//li/a[contains(text(),”first”)]/text()’),返回first item |
starts-with | 以字符串开头 | html.xpath(‘//li/a[starts-with(text(),”first”)]/text()’),返回first item |
This post is licensed under CC BY 4.0 by the author.