目录:
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)
/ 找根节点
// 找任意节点
* 表示任意节点名称,示例: //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>保存</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) # 输出: '窗前明月光'
↶ 返回首页 ↶