美文网首页Devs我爱编程
[爬虫基础] XPath 入门

[爬虫基础] XPath 入门

作者: 乌龟怕铁锤 | 来源:发表于2017-12-05 10:53 被阅读20次

    XPath是什么?

    • XPath 的全称为 XML Path Language
    • XPath使用路径形式的格式来标识XML格式文档中的节点
    • XPath是XSLT标准中主要的一部分
    • XPath 是W3C推荐的一个标准

    通俗的说: XPath就是一种在HTML中寻找节点的语法.

    例如一个简单的例子:

    <div class="cooking">
      <span lang="en">Everyday Italian</span>
    </div>
    

    获取其中的span元素,可以通过Xpath /div/span 来完成

    XPath在爬虫框架CasperJS和Selenium中大量的使用,但在Google出的最新爬虫框架Puppeteer中使用的是JQuery的Selector, 后续会单独写一篇文章介绍。

    XPath 不仅仅是这么简单,它有200多种内置的路径表达方式,下面我们来看几个主要的概念

    1.节点 (Nodes)

    每个节点就是一个独立完整的Tag标签或者是独立的值, 例如:

      <author>J K. Rowling</author> (节点 - 独立的标签)
      J K. Rowling   (节点 - 独立的值)
    

    节点有以下属性:

    • Parent (父节点, 0到1个)
      比如在上面简单的例子中,Span节点的父节点是div节点.

    • Children (子节点, 0到多个)
      比如在上面简单的例子中,div节点的子点是span节点.

    • Siblings (邻居节点,0到多个)
      比如在以下的html中,input的邻居节点有span节点和table节点

      <div>
          <span>input your name</span>
          <input>  </input>
          <table>  </table>
      </div>
    
    • Ancestors (祖先节点, 0到多个)
      比如在以下的html中,span节点的祖先节点有 div节点和body节点
      <body>
          <div>
              <span>
                  text
              </span>
          </div>
      </body>
    
    • Descendants(后辈节点, 0到多个)
      比如在上一个html中, body节点的后辈节点有div节点和span节点.

    2. 语法 (Syntax)

    比较常用的语法就7种,熟练使用这些基本上就足够用来寻找大部分的节点了。

    • 节点名字 - 选择所有该名字的节点
      比如 div 就表示选择所有div节点.

    • / - 根节点,表示目标文档中的最顶部节点。
      例如 /div, 就表示选择在目标文档顶部节点下的所有div节点。 注意只是在root节点下,跨层的孙辈节点就不包含在内了, 例如 /body/div 就不属于/div的选择了

    • // 当前节点下寻找,这里的寻找是不限制层级的,即当前节点下的所有后辈节点都会被搜索。

    例如使用 Selenium 可以有以下的写法:

    inputDiv = driver.find_element_by_xpath("//div[@class='login']") 
    inputElementUsername = inputDiv.find_element_by_xpath("//input[@name='email']")
    

    其中第一句是需拿在文档中寻找登陆div (这里driver指代当前页面), 第二句就是在找到的登陆div中 寻找email的输入框。 这里输入框并不一定在登陆div的第一层下。

    • . - 当前节点
      .. - 父节点
      这两个语法的含义和命令行中的.与..是一致的, . 代表当前节点 ..代表父节点 :
    ../button   在当前节点的父节点中寻找button节点
    ./button  在当前节点中寻找button节点
    
    • @ 属性选择, 在上面的例子中有出现过,当选择节点的时候,不仅仅可以通过节点名字来区别,还可以额外增加节点的属性。 例如下面的html
      <body>
            <div class="a"> a </div>
            <div class="b"> b </div>
      </body>
    

    当要获取body下的a div时, 可以通过指定class属性来寻找节点

        //div[@class="a"]
    
    • 声明 (Predicates)
      利用之前的几个语法已经可以完成节点定位的, 而这里的声明 (Predicates) 提供了一些高效率的节点定位函数:
    /bookstore/book[1]  -  选择第一个符合条件的book节点
    /bookstore/book[last()]  - 选择最后一个符合条件的book节点
    /bookstore/book[last()-1] -  选择倒数第二个符合条件的book节点
    /bookstore/book[position()<3] - 选择前二个符合条件的book节点,位置小于3,即1,2
    /bookstore/book[price>35.00] - 选择价格属性大于35的book节点, 这个price属于属性,可以根据需要调整
    
    • 通配符
      这个只需要了解 * 代表任意节点, 其他的没什么用

    • 多重路径选择
      通过 | 可以选择若干个路径, 例如:

    //book/title | //book/price - 选择所有在book节点下的title和price节点
    

    3. 例子

    这里针对一些复杂情况做说明并举例,如有需要请留言

    • 如何定位有多个class属性的元素?

    方法1 可以通过空格间隔写入多个class

      "//button[@class='btn btn-netease btn-sm js-btn-ok']"
    

    方法2 可以使用 and 连接多个class属性

    "//a[contains(@class,'btn') and contains(@class,'page_next')]"
    

    相关文章

      网友评论

        本文标题:[爬虫基础] XPath 入门

        本文链接:https://www.haomeiwen.com/subject/uodxixtx.html