10>>>解析库之Xpath解析器

10.解析库之Xpath解析器

今天将要学习的是另一款相当常用的解析器——Xpath。

 

前言

Xpath是一门在XML文档中查找信息的语言,可用来在XML文档中对元素和属性进行遍历。

Xpath的效率很高,使用广泛(也是数据分析师们必备的功能模块)。该选择器可以做到一句话完成多步操作。

欲使用Xpath,老样子还是要先导入模块

from lxml import etree

这条语句是不是出现了很熟悉的东西?

没错,我们在下载BeautifulSoup模块时也一道下载了lxml模块。看来这个模块真是多才多艺,不光能在BeautifulSoup中使用,自己单独也能起效。

在导入模块之后,我们的起手势还是启用解析库。

html = etree.HTML(文件名)  # 将待匹配的文本传入etree生成一个对象
eg:
html = etree.HTML(doc)

 

主要功能

一步一步来详细了解这个解析器的功能,先从最基础的开始。

首先创建一个范例html文件作为演示。

doc = '''
<html>
 <head>
  <base href='http://example.com/' />
  <title id='t1'>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html' a="xxx">Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html' class='li'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
   <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
  </div>
 </body>
</html>
'''

 

1.匹配所有节点

a = html.xpath('//*')  # 匹配所有的标签。//是固定的写法,必须要写的开头

2.匹配指定节点(结果为列表)

a = html.xpath('//head')  # 匹配所有的head标签

3.匹配子节点,子孙节点

# 一个杠表示儿子,两个杠表示后代
a = html.xpath('//div/a')  # 匹配div标签内部所有的儿子a标签
a = html.xpath('//body/a')  # 没有符合条件的儿子a标签
a = html.xpath('//body//a')  # 匹配div标签内容所有的后代a标签
a = html.xpath('//body//a')  # 也可以匹配到

4.父节点

a=html.xpath('//body//a[@href="image1.html"]')  # 属性查找 获取body内部所有的href=image1.html后代a标签
a = html.xpath('//body//a[@href="image1.html"]/..')  # ..表示查找上一级父标签
a = html.xpath('//title[@id="t1"]/..')  # ..表示查找上一级父标签
a = html.xpath('//body//a[1]')  # 从1开始取值
'''xpath选择器中中括号内部可以放属性也可以放位置数 从1开始'''
# 也可以这样(了解)
a = html.xpath('//body//a[1]/parent::*')

值得注意的是,Xpath解析器的计数方式和我们日常生活中的计数方式一致,第一就是1,第二就是2,不需要从0开始算。

5.文本获取

a = html.xpath('//body//a[@href="image1.html"]/text()')
a = html.xpath('//body//a/text()')  # 获取body内部所有后代a内部文本(一次性获取不需要循环)

6.属性获取

a = html.xpath('//body//a/@href')  # 获取body内部所有后代a标签href属性值(一次性获取不需要循环)
a = html.xpath('//title/@id')  # 获取title标签id属性值
# # 注意从1 开始取(不是从0)
a = html.xpath('//body//a[2]/@href')

7.属性多值匹配

a标签有多个class类,直接匹配就不可以了,需要用contains
a=html.xpath('//body//a[@class="li"]')  # 写等号就表示等于 不是包含
a = html.xpath('//body//a[contains(@class,"li")]/text()')  # 包含需要使用关键字contains

8.多属性匹配

# '''查找body标签内部所有class含有li或者name=items的a标签'''
a = html.xpath('//body//a[contains(@class,"li") or @name="items"]')
'''查找body标签内部所有class含有li并且name=items的a标签的内部文本'''
a = html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')

9.按序选择

# 取最后一个
a = html.xpath('//a[last()]/@href')
# 位置小于3的
a = html.xpath('//a[position()<3]/@href')  # position()关键字  用于定位
# 倒数第三个
a = html.xpath('//a[last()-2]/@href')

 

其他功能(了解)

10.节点轴选择

ancestor:祖先节点
# 使用了* 获取所有祖先节点
a = html.xpath('//a/ancestor::*')
# # 获取祖先节点中的div
a = html.xpath('//a/ancestor::div')
​
attribute:属性值
a = html.xpath('//a[1]/attribute::*')  # 查找a标签内部所有的属性值
​
child:直接子节点
a = html.xpath('//a[1]/child::*')
​
descendant:所有子孙节点
a = html.xpath('//a[6]/descendant::*')
​
following:当前节点之后所有节点
a = html.xpath('//a[1]/following::*')
a = html.xpath('//a[1]/following::*[1]/@href')
​
following-sibling:当前节点之后同级节点
a = html.xpath('//a[1]/following-sibling::*')
a = html.xpath('//a[1]/following-sibling::a')
a = html.xpath('//a[1]/following-sibling::*[2]/text()')
a = html.xpath('//a[1]/following-sibling::*[2]/@href')

 

Xpath爬取猪八戒数据

了解了Xpath的操作方法,接下来我们就可以用实战练练手了。

地址:shanghai.zbj.com/search/f/?kw=python
需求:爬取python相关的订单数据。包括企业名称、订单价格、成交数量、交易名称。

1.查看网页源代码,判断网页加载数据的方式。

第一步还是老黄历。稍加判断就知道这个网站是直接加载数据的。

2.向网站发出get请求

import requests
from bs4 import BeautifulSoup
from lxml import etree

res = requests.get('https://shanghai.zbj.com/search/f/',
                   params={'kw': 'python'}
                   )
x_html = etree.HTML(res.text)
# 分析标签特征并书写xpath语法筛选
# 1.先查找所有的外部div标签
div_list = x_html.xpath('/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div')  # 利用浏览器自动生成
# div_list = x_html.xpath('//div[@class="new-service-wrap"]/div')  # 自己写
# 2.循环获取每一个div标签
for div in div_list:
    price = div.xpath('.//span[@class="price"]/text()')
    company_name = div.xpath('./div/div/a[1]/div[1]/p/text()')
    order_num = div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()')
    info = div.xpath('./div/div/a[2]/div[2]/div[2]/p/text()')
    print(info)

接下来再根据需要保存数据就可以了。

上一篇:selenium学习笔记(三)WebDriver API -- 元素定位


下一篇:9/28