xpath解析

一.定义:

  XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言,同样适用于HTML文档的检索

二.示例HTML代码

<ul class="CarList">
<li class="bjd" id="car_001" href="http://www.bjd.com/">
<p class="name">布加迪</p>
<p class="model">威航</p>
<p class="price">2500万</p>
<p class="color">红色</p>
</li>

<li class="byd" id="car_002" href="http://www.byd.com/">
<p class="name">比亚迪</p>
<p class="model">秦</p>
<p class="price">15万</p>
<p class="color">白色</p>
</li>
</ul>

三.匹配演示

1、查找所有的li节点
   //li
2、获取所有汽车的名称: 所有li节点下的子节点p的值 (class属性值为name)
   //li/p[@class="name"]
3、找比亚迪车的信息: 获取ul节点下第2个li节点的汽车信息
   //ul[@class="CarList"]/li[2]/p                           
4、获取所有汽车的链接: ul节点下所有li子节点的href属性的值
   //ul[@class="CarList"]/li/@href

# 只要涉及到条件,加 []
# 只要获取属性值,加 @

四选取节点

1、// :从所有节点中查找(包括子节点和后代节点)
2、@  :获取属性值
   # 使用场景1(属性值作为条件)
     //div[@class="movie-item-info"]
   # 使用场景2(直接获取属性值)
     //div[@class="movie-item-info"]/a/img/@src

五.匹配多路径(或)

xpath表达式1 | xpath表达式2 | xpath表达式3

六.常用函数

1、contains() :匹配属性值中包含某些字符串节点
   # 查找id属性值中包含字符串 "car_" 的 li 节点
     //li[contains(@id,"car_")]
2、text() :获取节点的文本内容
   # 查找所有汽车的价格
     //ul[@class="CarList"]/li/p[@class="price"]/text()

 匹配规则

1、节点对象列表
   # xpath示例:       
  //div、//div[@class="student"]、//div/a[@title="stu"]/span
2、字符串列表
   # xpath表达式中末尾为: @src、@href、text()

xpath高级

1、基准xpath表达式: 得到节点对象列表
2、for r in [节点对象列表]:
username = r.xpath('./xxxxxx') # 此处注意遍历后继续xpath一定要以: . 开头,代表当前节点

写程序注意

# 最终目标: 不要使你的程序因为任何异常而终止
1、页面请求设置超时时间,并用try捕捉异常,超过指定次数则更换下一个URL地址
2、所抓取任何数据,获取具体数据前先判断是否存在该数据,可使用列表推到式
# 多级页面数据抓取注意
1、主线函数: 解析一级页面函数(将所有数据从一级页面中解析并抓取)

lxml解析库

安装

sudo pip3 install lxml

使用流程

1、导模块
   from lxml import etree
2、创建解析对象
   parse_html = etree.HTML(html) #html需字符串res.text
3、解析对象调用xpath
   r_list = parse_html.xpath('xpath表达式')
用xpath 结果一定是列表

示例:html样本

<div class="wrapper">
    <a href="/" id="channel">新浪社会</a>
    <ul id="nav">
        <li><a href="http://domestic.sina.com/" title="国内">国内</a></li>
        <li><a href="http://world.sina.com/" title="国际">国际</a></li>
        <li><a href="http://mil.sina.com/" title="军事">军事</a></li>
        <li><a href="http://photo.sina.com/" title="图片">图片</a></li>
        <li><a href="http://society.sina.com/" title="社会">社会</a></li>
        <li><a href="http://ent.sina.com/" title="娱乐">娱乐</a></li>
        <li><a href="http://tech.sina.com/" title="科技">科技</a></li>
        <li><a href="http://sports.sina.com/" title="体育">体育</a></li>
        <li><a href="http://finance.sina.com/" title="财经">财经</a></li>
        <li><a href="http://auto.sina.com/" title="汽车">汽车</a></li>
    </ul>
</div>

实现代码:

# 创建解析对象
parse_html = etree.HTML(html)
# 调用xpath返回结束,text()为文本内容
r1 = parse_html.xpath('//a/text()')
#print(r1)
#['新浪社会', '国内', '国际', '军事', '图片', '社会', '娱乐', '科技', '体育', '财经', '汽车']

# 提取所有的href的属性值
r2 = parse_html.xpath('//a/@href')[1:]
#print(r2)
#['http://domestic.sina.com/', 'http://world.sina.com/', 'http://mil.sina.com/', 'http://photo.sina.com/', 'http://society.sina.com/', 'http://ent.sina.com/', 'http://tech.sina.com/', 'http://sports.sina.com/', 'http://finance.sina.com/', 'http://auto.sina.com/']

# 提取所有href的值,不包括 / 
r3 = parse_html.xpath('//ul[@id="nav"]/li/a/@href')
#print(r3)
#['http://domestic.sina.com/', 'http://world.sina.com/', 'http://mil.sina.com/', 'http://photo.sina.com/', 'http://society.sina.com/', 'http://ent.sina.com/', 'http://tech.sina.com/', 'http://sports.sina.com/', 'http://finance.sina.com/', 'http://auto.sina.com/']
# 获取 图片、军事、...,不包括新浪社会
r4 = parse_html.xpath('//ul[@id="nav"]/li/a/text()')
for r in r4:
    print(r)
#国内 国际 军事 图片 社会 娱乐 科技 体育 财经 汽车

xpath最常使用方法

1、先匹配节点对象列表
  # r_list: ['节点对象1','节点对象2']
  r_list = parse_html.xpath('基准xpath表达式')
2、遍历每个节点对象,利用节点对象继续调用 xpath
  for r in r_list:
        name = r.xpath('./xxxxxx')
        star = r.xpath('.//xxxxx')
        time = r.xpath('.//xxxxx')