——为什么要学习xpath和lxml?
lxml是一款高性能的 Python HTML/XML 解析器,我们可以利用XPath,来快速的定位特定元素以及获取节点信息。
-
什么是xpath
XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML 文档中对元素和属性进行遍历。
W3School官方文档:http://www.w3school.com.cn/xpath/index.asp
-
认识xml
1. html和xml的区别
2. xml的树结构
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
上面的xml内容可以表示为下面的树结构
上面的这种结构关系在xpath被进一步细化
3. xpath的节点关系
每个XML的标签我们都称之为节点,其中最顶层的节点称为根节点。
4. 选取节点
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式
非常相似。
我们将在下面的例子中使用这个 XML 文档。
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
- 下面,列出了最有用的表达式:
表达式 |
描述 |
---|---|
nodename |
选中该元素。 |
/ |
从根节点选取、或者是元素和元素间的过渡。 |
// |
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. |
选取当前节点。 |
.. |
选取当前节点的父节点。 |
@ |
选取属性。 |
text() |
选取文本。 |
实例:
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 |
结果 |
---|---|
bookstore |
选择bookstore元素。 |
/bookstore |
选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book |
选取属于 bookstore 的子元素的所有 book 元素。 |
//book |
选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book |
选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置 |
//book/title/@lang |
选择所有的book下面的title中的lang属性的值。 |
//book/title/text() |
选择所有的book下面的title的文本。 |
- 查找特定的节点
路径表达式 |
结果 |
---|---|
/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 通配符可用来选取未知的 XML 元素。
通配符 |
描述 |
---|---|
* |
匹配任何元素节点。 |
@* |
匹配任何属性节点。 |
node() |
匹配任何类型的节点。 |
实例:
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 |
结果 |
---|---|
/bookstore/* |
选取 bookstore 元素的所有子元素。 |
//* |
选取文档中的所有元素。 |
//title[@*] |
选取所有带有属性的 title 元素。 |
-
xml小结
xpath的概述XPath (XML Path Language),解析查找提取信息的语言
xml是和服务器交互的数据格式和json的作用一致
html是浏览器解析标签数据显示给用户
xpath的节点关系:根节点,子节点,父节点,兄弟节点,子节点,后代节点
xpath的重点语法获取任意节点://
xpath的重点语法根据属性获取节点:标签[@属性 = '值']
xpath的获取节点属性值:@属性值
xpath的获取节点文本值:text()
-
lxml库
——上面讲了xpath的语法,那么在python爬虫代码中我们如何使用xpath呢? 对应的我们需要使用lxml库
1. lxml的安装
安装方式:pip install lxml
2. lxml的使用
- 基本展示:
import requests
from lxml import etree
r = requests.get('https://www.baidu.com')
r.encoding = r.apparent_encoding
html = etree.HTML(r.text)
print(html)
li_list = html.xpath('//title/text()')
print(li_list)
运行结果:
<Element html at 0x297c19dba08>
['百度一下,你就知道']
>>>
- 实例展示
目标网站:豆瓣图书 Top 250 https://book.douban.com/top250
提取数据:书名、评分、推荐语、链接
这是上文的实例,这里不多讲,我们直接讲实用的方法,你会发现xpath很好用,也很方便
如下,用谷歌浏览器快速提取标签的路径
我们提取的a标签路径为:
//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a
一大串,但是我们不需要这长的一串
在上文我们分析过,每本书信息在<tr class="item">标签下,所以我们需要的是标签tr
之后的路径,即是/td[2]/div[1]/a
单个html页面的所有书books =html.xpath('//tr[@class="item"]')
用for语句遍历books,for book in books
,上面说了.
表示当前节点,所以标签a路径为 a_path =book.xpath('./td[2]/div[1]/a')
书名 title = book.xpath('./td[2]/div[1]/a/@title')
链接 link = book.xpath('./td[2]/div[1]/a/@href')
通过这个方法,可以快速上手,注意xpath提取信息返回列表
代码实现:
import requests
from lxml import etree
# 如果提取不成功,返回空字符串,成功则取值
def info(list_name):
if list_name==[]:
return ''
else:
return list_name[0]
# 用Xpath提取数据
def get_data(url,headers):
r= requests.get(url,headers = headers)
html = etree.HTML(r.text)
books =html.xpath('//tr[@class="item"]')
for book in books:
title = book.xpath('./td[2]/div[1]/a/@title')
link = book.xpath('./td[2]/div[1]/a/@href')
num = book.xpath('./td[2]/div[2]/span[2]/text()')
introduce = book.xpath('./td[2]/p[2]/span/text()')
print(info(title),info(num),info(introduce),info(link))
if __name__ == "__main__":
for i in range(10):
url = 'https://book.douban.com/top250?start='+str(i*25)
headers = {'User-Agent': 'Mozilla/5.0'}
get_data(url,headers)
-
xpath小结
lxml库的安装: pip install lxml
lxml的导包:from lxml import etree
lxml转换解析类型的方法:etree.HTML(text)
lxml解析数据的方法:data.xpath("//div/text()")
需要注意lxml提取完毕数据的数据类型都是列表类型
如果数据比较复杂:先提取大节点, 在遍历小节点操作
网友评论