python爬虫从入门到放弃之八:Xpath

——为什么要学习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的区别
python爬虫从入门到放弃之八:Xpath_第1张图片


2. xml的树结构


  Everyday Italian 
  Giada De Laurentiis 
  2005 
  30.00 


  Harry Potter 
  J K. Rowling 
  2005 
  29.99 


  Learning XML 
  Erik T. Ray 
  2003 
  39.95 


上面的xml内容可以表示为下面的树结构

python爬虫从入门到放弃之八:Xpath_第2张图片

上面的这种结构关系在xpath被进一步细化

3. xpath的节点关系

每个XML的标签我们都称之为节点,其中最顶层的节点称为根节点。

python爬虫从入门到放弃之八:Xpath_第3张图片

python爬虫从入门到放弃之八:Xpath_第4张图片


4. 选取节点

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

我们将在下面的例子中使用这个 XML 文档。






  Harry Potter
  29.99



  Learning XML
  39.95




  • 下面,列出了最有用的表达式:
表达式 描述
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)

运行结果:


['百度一下,你就知道']
>>> 


  • 实例展示

目标网站:豆瓣图书 Top 250 https://book.douban.com/top250

提取数据:书名、评分、推荐语、链接

这是上文的实例,这里不多讲,我们直接讲实用的方法,你会发现xpath很好用,也很方便

如下,用谷歌浏览器快速提取标签的路径

python爬虫从入门到放弃之八:Xpath_第5张图片

我们提取的a标签路径为: //*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a一大串,但是我们不需要这长的一串

在上文我们分析过,每本书信息在标签下,所以我们需要的是标签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提取完毕数据的数据类型都是列表类型

如果数据比较复杂:先提取大节点, 在遍历小节点操作


>>>阅读更多文章请点击以下链接:

python爬虫从入门到放弃之一:认识爬虫
python爬虫从入门到放弃之二:HTML基础
python爬虫从入门到放弃之三:爬虫的基本流程
python爬虫从入门到放弃之四:Requests库基础
python爬虫从入门到放弃之五:Requests库高级用法
python爬虫从入门到放弃之六:BeautifulSoup库
python爬虫从入门到放弃之七:正则表达式
python爬虫从入门到放弃之八:Xpath
python爬虫从入门到放弃之九:Json解析
python爬虫从入门到放弃之十:selenium库
python爬虫从入门到放弃之十一:定时发送邮件
python爬虫从入门到放弃之十二:多协程
python爬虫从入门到放弃之十三:Scrapy概念和流程
python爬虫从入门到放弃之十四:Scrapy入门使用
python爬虫从入门到放弃之十五:Scrapy爬取多个页面
python爬虫从入门到放弃之十六:Xpath简化
python爬虫从入门到放弃之十七:常见反爬手段

你可能感兴趣的:(python爬虫从入门到放弃之八:Xpath)