上面我们提到了正则表达式来提取页面的数据,但是有的小可爱可能觉得,正则有亿点点的难用,有没有更简单一点的数据提取方式呢?
接下来就给大家介绍一款相对比较简单的数据提取的方式Xpath
为什么要学习XPATH
我们可以利用Xpath
来快速的定位特定元素以及获取节点信息,我们可以理解为对html
或xml
形式的文本提取特定的内容
什么是XPATH
Xpath
全称是xml path language
,Xpath
是一门在HTML/XML
文档中查找信息的语言,可用来在HTML/XML
文档中对元素和属性进行遍历,XPath
使用路径表达式来选取HTML/XML
文档中的节点或者节点集
看到这里有的小伙伴可能会对XML
比较陌生,XML
是可扩展标记语言,被设计为传输和存储数据,其焦点是数据的内容,而HTML
是超文本标记语言,主要是显示数据以及如何更好显示
节点的概念
每个HTM
L、XML
的标签我们都称之为节点,其中最顶层的节点称为根节点
下面是一个XML
格式的数据,<book>
就是根节点
<book>
<title>hello world</title>
<author>juran</author>
<year>2019</year>
<book>
HTML格式的数据,<html>
就是我们的根节点
<html>
<head>
<title>测试</title>
</head>
<body>
<li class="item-0">first item</li>
<li class="item-1">fourth item</li>
<div>
<li class="item-0">fifth item</li>
</div>
<span>
<li class="item-0">sixth item</li>
<div>
<li class="item-0">eighth item</li>
</div>
</span>
</body>
</html>
当然除了根节点的概念,还有子节点、同胞节点等
常用节点选择工具
- chrome插件 XPath Helper
- Firefox插件 XPath Checker
这里推荐大家用谷歌的浏览器,XPath Helper
插件是需要安装的,安装也比较简单,这里我不做详细的介绍。
安装成功后,按Ctrl+shift+x
会弹出如下的界面
节点选择语法
XPath使用路径表达式来选取XML文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
表达式 | 描述 |
---|---|
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性,从选中的节点标签中获取指定的属性 |
text() | 获取标签中的文本 |
使用chrome插件选择标签时候,选中时,选中的标签会添加属性class='xh-highlight'
这里给大家写一些Xpath
的语法,大家可以找网站试一试
获取网站的title
/html/head/title/text()
获取图片的地址
//div[@class="xxx"]/img/@src
获取标签下的文本
//li/div[@class="j-r-list-c"]/div/a/text()
节点修饰语法
查找某个特定的节点或者包含某个指定的值的节点
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=’eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
这里需要注意的是,Xpath
中第一个元素的位置是1
lxml库
刚才说了Xpath
的语法,那我们接下来就要在Python中使用,Python中提供了一个模块lxml,lxml模块可以利用XPath规则语法,来快速的定位HTML\XML 文档中特定元素以及获取节点信息(文本内容、属性值)
lxml的简单使用
# 导入lxml的etree库
from lxml import etree
# 利用etree.HTML 将字符串转化为Element对象,Element对象具有xpath的方法,可以接收bytes和str的数据类型
html = etree.HTML(text)
注意:lxml可能会修正错你的HTML代码!!!!
一个简单的小练习
from lxml import etree
text = '''
<div>
<ul>
<li><strong>one</strong>
<li class='item-1'><a href="http://fenqi.renren.com/" target="_blank">two</a></li>
<li><a href="https://licai.renren.com/" target="_blank">three</a></li>
<li><a href="http://www.woxiu.com/" target="_blank">five</a></li>
<li><a href="http://zhibo.renren.com/" target="_blank">six</a></li>
<li class='item-1'><a href="http://www.renren.com/" target="_blank">serven</a></li>
<li class='item-1'><a href="https://www.kaixin.com" target="_blank">eight</li>
</ul>
'''
html = etree.HTML(text)
获取clas=item-1的li标签下的a标签的href
ret1 = html.xpath('//li[@class="item-1"]/a/@href')
print(ret1)
获取clas=item-1的li标签下的a标签的文本
ret2 = html.xpath('//li[@class="item-1"]/a/text()')
print(ret2)
每个li是一条新闻 把url和title组成字典
for href in ret1:
item = {}
item['href'] = href
item['title'] = ret2[ret1.index(href)]
print(item)
print("="*100)