zoukankan      html  css  js  c++  java
  • Python 爬虫 解析库的使用 --- XPath

    一、使用XPath 

    XPath ,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言。它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。

    所以在爬虫时,我们完全可以使用XPath来做相应的信息提取。本次随笔中,我们就介绍XPath的基本用法。

    1.XPath概览

    XPath的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过100个内建函数,用于字符串、数值、时间的匹配以及节点。序列的处理等。几乎所有我们想要定位的节点,都可以用XPath来选择。

    XPath与1999年11月16日成为W3C标准,它被设计为供XSLT/XPointer以及其他XML解析软件使用,更多的文档可以访问其官方网站:http://www.w3school.com.cn/xpath/index.asp

    2.XPath 常用规则

    我列举了几个常用规则:

    表达式 描述
    nodename 选取此节点的所有子节点
    / 从当前节点选取直接子节点
    // 从当前节点选取子孙节点
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性

    这里列举出XPath的常用匹配规则,示例如下:

    //title[@lang='eng']

    这就是一个XPath规则,它代表选择所有名称为title,同时属性lang的值为eng的节点。

    后面会通过Python的lxml库,利用XPath进行HTML 的解析。

    3.准备工作

    使用之前要安装好lxml库

    4.实例引入

    现在通过实例来感受一下使用XPath来对网页进行解析的过程,相关代码如下:

    省略

    首先我们导入 from lxml import etree ,然后声明了一段HTML 文本,调用HTML类进行初始化,这样就成功构造了一个XPath解析对象。需要注意的是etree模块可以自定修正HTML文本。

    这里我们调用tosting()方法即可输出修正后的HTML文本,但是结果是bytes类型。这里利用decode()方法将其转成str类型。

    另外,也可以直接读取文本文件进行解析。

    5.所有节点

    我们一般会用//开头的XPath规则来获取所有符合要求的节点。

    *代表匹配所有节点,也就是整个HTML文本中的所有节点都会被获取。返回形式是一个列表,每一个元素是Element类型,其后跟了节点的名称,如html、body、div、ul、li、a等,所有节点都包含在列表中了。

    当然,匹配也可以指定节点名称。//后直接加上节点名称即可。,列表获取其中直接用中括号加索引。

    6.子节点

    我们通过/或//即可查找元素的子节点或者子孙节点。

    result = html.xpath('//li/a')

    这里通过追加/a即选择了所有li节点的所有直接a子节点。因为//li用于选中所有li节点,/a用于选中li节点的所有直接子节点a,二者组合在一起即获取所有li节点的所有直接a子节点。

    此处的/用于获取直接子节点,如果想要获取所有子孙节点,就可以使用//。

    result = html.xpath('//ul//a')

    7.父节点

    我们知道通过/或//即可查找元素的子节点或者子孙节点,那么假如我们知道了自己子节点,怎样来查找父节点呢?

    比如,现在首先选中href属性为link4.html的a节点,然后再获取其父节点,然后再获取其class属性

    result = html.xpath('//a[@href=link4.html"]/../@class')

    同时我们也可以通过parent::来获取父节点

    result = html.xpath('//a[@href=link4.html"]/parent::*/@class')

    8.属性匹配

    在获取的时候,我们还可以用@符号进行属性过滤。比如,如果要选取class为item-0的li节点。

    result = html.xpath('//li[@class="item-0"]')

    这里我们通过加入[@class="item-0"],限制了节点的class属性为item-0,而HTML 文本中符合条件的li节点有两个,会返回出符合的,至于正不正确,后面在验证。

    9.文本获取

    我们用XPath中的text()方法获取节点中的文本,接下来尝试获取前面li节点中的文本

    result = html.xpath('//li[@class="item-0"]/text()')

    奇怪的是,我们并没有获取到任何文本,只获取到了一个换行符,这是为什么呢?因为XPath中text()前面是/,而此处/的含义是选取直接子节点,很明显li的直接子节点都是a节点。文本都是在a节点内部的,所以这里匹配到的结果就是被修正的li节点内部的换行符,因为自动修正的li节点的为标签换行了。

    因此想要获取li字节内部的文本,就有两种方式,一种就是先选取a节点再获取文本,另一种就是使用//。接下来,我们来看一下二者的区别。

    第一种:

    首先获取a节点再获取文本

    10.属性获取

    有时候,某些节点的某个属性可能有多个值

    @符号

    11.属性多值获取

    用contains()函数,第一个参数传入属性名称,第二个参数传入属性值。只要此属性包含所传入的属性值,就可以完成匹配了。

    12.多属性匹配

    另外,我们还坑遇到一种情况,那就是根据多个属性确定一个节点,这时候就需要同时匹配多个属性。

    运算符及其介绍

    运算符 描述 实例 返回值
    or age=19 or age=20 如果age是19,则返回true。如果age是21,则返回false
    and age>19 and age <21 如果age是20,则返回true。如果age是18,则返回false
    mod 计算除法的余数 5 mod 2 1
    | 计算两个节点集 //book | //cd 返回所有拥有book跟cd元素的节点集
    + 加法 6+4 10
    - 减法 6-4 2
    * 乘法 6*4 24
    div 除法 8 div 4 2
    = 等于 age-=19 如果age是19,则返回true,如果age是20,则返回false
    != 不等于 age1=19 如果age是18则返回true,如果age是19,则返回false
    > 大于 age>19  
    >= 大于或等于 age>=19  
    < 小于 age<19  
    <= 小于或等于 age<=19  

    13.顺序选择

    有时候,我们在选择的时候某些属性可能同时匹配了多个节点,但是只想要其中的某个节点,如第二个节点或者最后一个节点,该怎么办?

    这时候可以利用中括号传入索引的方法获取特定次序的节点

    14.节点轴选择

    子元素、兄弟元素、父元素、祖先元素,

    15.结语

     好好学习,天天向上

  • 相关阅读:
    log4net使用
    第二天 ado.net, asp.net ,三层笔记
    第一天上传我的前端基础笔记
    开通博客的第一天上传我的C#基础笔记。
    VS 星期作业 if else的应用 做一个受不受异性欢迎的小程序
    ****************VS编码操作实践******************
    VS基本学习之(变量与常量)
    VS的基本学习
    2016.4.10 重生
    【python之路3】if 语句
  • 原文地址:https://www.cnblogs.com/zhangrenguo/p/10500919.html
Copyright © 2011-2022 走看看