【python 第三方库】lxml

2024-01-25 00:00:00

目录:

lxml 模块介绍

lxml 模块专门用于处理 XML 和 HTML 文档。

$ pip3 install lxml

执行以下脚本,如果没有报错并输出版本号,说明安装成功。

import lxml

print(lxml.__version__)

示例

xpath() 总是返回列表。

from lxml import etree

htmldemo = '''
<div>
    <p class="title">示例标题</p>
    <a href="link1.html">第一个链接</a>
</div>
'''

tree = etree.HTML(htmldemo)
result = tree.xpath('//div/p/text()')
for node in result:
    print(node)

xpath 节点介绍

/  找根节点
// 找任意节点
*  表示任意节点名称,示例: //body/*   表示找 body 所有后代标签
|  或者关系,示例: //p|//div 表示找出所有 p 标签和所有 div 标签

[@attribute=value]

根据属性值完全匹配寻找节点。

from lxml import etree

html = '''
<div>
    <a href="link1.html" class="item">first</a>
    <a href="link2.html" class="item active">second</a>
</div>
'''

tree = etree.HTML(html)
# 选取 href 属性值为 "link1.html" 的 <a> 节点
result = tree.xpath('//a[@href="link1.html"]')

for node in result:
    print(node.tag) # 输出: 'a'
    print(node.get('href')) # 输出: 'link1.html'
    print(node.get('class')) # 输出: 'item'
    print(etree.tostring(node).decode('utf-8')) # 输出: <a href="link1.html" class="item">first</a>

[contains(@attribute, value)]

根据属性值部分匹配寻找节点,常见的 class 有多个类名,只要包含一个类名,就会匹配成功。

from lxml import etree

html = '''
<li class="li li-first">
    <a href="link.html">fifth item</a>
</li>
<li class="item-1">
    <a href="link2.html">second item</a>
</li>
'''
tree = etree.HTML(html)

# 选取 class 属性值中包含字符串 "li" 的 <li> 节点
result = tree.xpath('//li[contains(@class, "li")]/a')
for node in result:
    print(node.tag) # 输出: 'a'
    print(node.get('href')) # 输出: 'link.html'
    print(node.text) # 输出: 'fifth item'
    print(etree.tostring(node).decode('utf-8')) # 输出: <a href="link.html">fifth item</a>

[contains(text(), value)]

节点文本包含匹配。如下示例,寻找文字是 “保存” 的按钮。

from lxml import etree

html = '''
<div>
    <button>保存</button>
    <button>取消</button>
</div>
'''
tree = etree.HTML(html)

# 选取文本内容包含“关键词”的<p>节点
result = tree.xpath('//button[contains(text(), "保存")]')
for node in result:
    print(node.tag) # 输出: 'button'
    print(node.get('href')) # 输出: None
    print(node.text) # 输出: '保存'
    print(etree.tostring(node).decode('utf-8')) # 输出: <button>&#20445;&#23384;</button>

[starts-with(@attribute, value)]

寻找属性值以指定字符串开头的节点。

from lxml import etree

html = '''
<body>
    <div id="aa">aa</div>
    <div id="ab">ab</div>
    <div id="ac">ac</div>
    <div id="ba">ba</div>
</body>
'''
tree = etree.HTML(html)

# 选取 id 属性值以 "b" 开头的所有 <div> 节点的文本
result = tree.xpath('//div[starts-with(@id, "b")]')
for node in result:
    print(node.text) # 输出: 'ba'

从前往后找第几个节点

from lxml import etree

html = '''
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</body>
'''
tree = etree.HTML(html)

# 获取第一个 div 标签
result = tree.xpath('//div[1]')
for node in result:
    print(node.text) # 输出: '1'

result = tree.xpath('//div[2]')
for node in result:
    print(node.text) # 输出: '2'

从后往前找第几个节点

from lxml import etree

html = '''
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</body>
'''
tree = etree.HTML(html)

# 获取最后一个 div 标签
result = tree.xpath('//div[last()]')
for node in result:
    print(node.text) # 输出: '4'

# 获取倒数第二个 div 标签
result = tree.xpath('//div[last() - 1]')
for node in result:
    print(node.text) # 输出: '3'

找指定位置的节点

from lxml import etree

html = '''
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</body>
'''
tree = etree.HTML(html)

# 获取第三个 div 标签
result = tree.xpath('//div[position() = 3]')
for node in result:
    print(node.text) # 输出: '3'

# 获取前三个 div 标签
result = tree.xpath('//div[position() <= 3]')
for node in result:
    print(node.text) # 输出: '1', '2', '3'

找当前节点的父节点

通常父节点没有明显特征,但子节点有,可以通过子节点找到父节点。

//[@id='china']/..

找当前节点后面的节点

//[@id='china']/following-sibling::div

找当前节点前面的节点

//[@id='china']/preceding-sibling::div

获取属性值

示例:获取 a 标签的 href 属性值。

第一种方法通过 xpath() 方法种 @href 获取属性值,如果要获取 class 值,这里就是 @class。

from lxml import etree

htmldemo = '''
<div>
    <a href="link1.html">第一个链接</a>
</div>
'''

tree = etree.HTML(htmldemo)
# 在 xpath() 方法中 @href 获取属性值
result = tree.xpath('//a/@href')
for node in result:
    print(node) # 输出: link1.html

第二种方法通过节点的 get() 方法获取属性值。

from lxml import etree

htmldemo = '''
<div>
    <a href="link1.html">第一个链接</a>
</div>
'''

tree = etree.HTML(htmldemo)
result = tree.xpath('//a')
for node in result:
    # 在节点中通过 get() 方法获取属性值
    print(node.get('href')) # 输出: link1.html

获取文本值

第一种方法在 xpath() 种通过 text() 获取文本值。

from lxml import etree

htmldemo = '''
<div>
    <p>窗前明月光</p>
</div>
'''

tree = etree.HTML(htmldemo)
result = tree.xpath('//p/text()')
for node in result:
    print(node) # 输出: '窗前明月光'

第二种方法通过节点的 text 属性获取文本值。

from lxml import etree

htmldemo = '''
<div>
    <p>窗前明月光</p>
</div>
'''

tree = etree.HTML(htmldemo)
result = tree.xpath('//p')
for node in result:
    print(node.text) # 输出: '窗前明月光'

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: