我们知道 xpath 是一门语言,它可以在 XML 文档中查找信息,并且支持HTML,通过元素和属性行为提取信息,比正则表达式厉害并且简单。
这里要注意的是,要想使用 xpath,就必须先安装 lxml 库(这些常用库在前面的文章有安装步骤),然后倒入 lxml 中的 etree 模块即可操作,下面我们开始来搞案例吧:
一、XPath的简单使用
- 首先我们先导入相关的模块并准备好数据源(这里使用字符串模拟网页源码):
from lxml import etree
html = '''
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>测试-常规用法</title>
</head>
<body>
<div id="content">
<ul id="useful">
<li>这是第一条信息</li>
<li>这是第二条信息</li>
<li>这是第三条信息</li>
</ul>
<ul id="useless">
<li>不需要的信息1</li>
<li>不需要的信息2</li>
<li>不需要的信息3</li>
</ul>
<div id="url">
<a href="http://luchangyin.com">飞牛数据采集</a>
<a href="http://luchangyin.com/data/" title="飞牛数据库">点我获取数据</a>
</div>
</div>
</body>
</html>
'''
- 接下来我们实例化树状结构并对其进行操作:
selector = etree.HTML(html) # 将源码转换成树状实例
#提取文本
content = selector.xpath('//ul[@id="useful"]/li/text()')
for each in content:
print(each)
#获取链接
link = selector.xpath('//a/@href')
for lk in link:
print(lk)
#获取标题
title = selector.xpath('//a/@title')
print(title[0])
运行结果如下:
0.png
二、XPath 的特殊使用
- 获取属性名前几个字母相同的标签的值,代码如下:
html2 = '''
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test-1">需要的内容1</div>
<div id="test-2">需要的内容2</div>
<div id="textfault">需要的内容3</div>
</body>
</html>
'''
1.1 接下来我们可以使用 starts-with 来进行操作:
# 获取多个类似属性的值的内容
selector = etree.HTML(html2)
content = selector.xpath('//div[starts-with(@id, "test")]/text()')
for text in content:
print(text)
运行结果如下:
1.png
- 获取嵌套标签同等级的文本数据,数据格式入下:
html3 = '''
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test3">
我左青龙,
<span id="tiger">
右白虎,
<ul>上朱雀,
<li>下玄武。</li>
</ul>
飞牛在当中,
</span>
龙头在胸口。
</div>
</body>
</html>
'''
2.1 这里如果想获取某个标签里的文本,不过有木有嵌套标签,我们指定下这个标签并直接获取其文本即可:
# 获取嵌套的内容
selector = etree.HTML(html3)
content = selector.xpath('//div[@id="test3"]/text()')
for each in content:
print(each.replace('\n ', '').replace(' ', ''))
运行效果如下:
2.png
- 获取标签以及嵌套标签的全部数据:
# 获取标签里的全部内容
selector = etree.HTML(html3)
data = selector.xpath('//div[@id="test3"]')[0]
info = data.xpath('string(.)').replace('\n','').replace(' ', '')
print(info)
运行效果如下:
3.png
网友评论