xpath操作html节点入门

2018-11-13 技术笔记 1

在写爬虫的过程中,难免要和HTML DOM节点打交道,xpath就是一门优秀的查找遍历HTML节点的语法,通过分析豆瓣图书页面 重构 来掌握xpath的所有语法和功能

首先,通过爬虫爬取了页面的选择器 response(这部分内容可通过查看 scrapy入门 来获取更多信息),接下来,就可以尝试获取页面的内容了

查找获取书名

在页面元素中找到书名所在的节点

<h1>
    <span property="v:itemreviewed">重构</span>
    <div class="clear"></div>
</h1>

因为这个节点没有特定的 classid 属性,所以我们只能通过 span 标签的 property 属性,通过查找发现整个页面只有一个 property 属性值为 "v:itemreviewed" 的标签,所以我们得到书名的路径为

response.xpath('//span[@property="v:itemreviewed"]/text()')

xpath的基本符号有:
// 表示从当前节点的所有下级节点查找,因为当前节点是 response 节点,所以当前 // 表示从查找整个 HTML 中的所有 span 标签
[] 查找修饰符,用来界定查找的条件
@ 表示标签属性
text() 表示标签包含的文本信息

获取书的封面图片

//封面图片所在div
<div id="mainpic" class="">
  <a class="nbg" href="https://img3.doubanio.com/view/subject/l/public/s1669771.jpg" title="重构">
    <img src="https://img3.doubanio.com/view/subject/l/public/s1669771.jpg" title="点击看大图" alt="重构" rel="v:photo" style="width: 135px;max-height: 200px;">
  </a>
</div>

通过查找发现 id="mainpic"div 标签和 class="nbg"a 标签都是唯一的,同时也有 a 标签的 href 属性和 img 标签的 src 属性来获取到图片地址,所以我们可以通过这四种方法来获取图片链接地址

response.xpath('//div[@id="mainpic"]/a/@href')
response.xpath('//div[@id="mainpic"]//img/@src')
response.xpath('//a[@class="nbg"]/@href')
response.xpath('//a[@class="nbg"]/img/@src')

在以上的查找中, / 表达式用于查找一级的子节点,当跨度超过一级的查询只能通过 // 来获取

获取书本信息

<div id="info" class="">
    <span>
      <span class="pl"> 作者</span>:<a class="" href="/search/Martin%20Fowler">Martin Fowler</a>
    </span><br>
    <span class="pl">出版社:</span> 中国电力出版社<br>
    <span class="pl">副标题:</span> 改善既有代码的设计<br>
    <span class="pl">原作名:</span> Refactoring: Improving the Design of Existing Code<br>
    <span>
      <span class="pl"> 译者</span>:<a class="" href="/search/%E7%86%8A%E8%8A%82">熊节</a>
    </span><br>
    <span class="pl">出版年:</span> 2003-8-1<br>
    <span class="pl">页数:</span> 464<br>
    <span class="pl">定价:</span> 68.00元<br>
    <span class="pl">装帧:</span> 平装<br>
    <span class="pl">ISBN:</span> 9787508315546<br>
</div>

所有的书本信息都包含在同一个 div 之下,所以我们可以先获取到整个 div,然后递归获取某个信息

infoDiv = response.xpath('//div[@id="info"]/')
author = infoDiv.xpath('//span[text()="作者"]/../a/text()')
translator = infoDiv.xpath('//span[text()="译者"]/../a/text()')

作者信息比较容易获取,因为作者名和定义在同一个 span 标签中,这里面涉及到的属性为 .. 表示获取到父级节点,同时 . 表示当前节点
但是,我们怎么获取到其他信息呢
首先,剩余的信息都没有被标签所包围,我们可以通过 infoDiv.xpath('/text()') 来获取到所有的文字,这里要注意,通过 <br> 标签分割的文字查找后会产生一个对应的数组,我们可以通过一一对应的关系来获取到数组的信息。但是不同页面对应的书本信息可能不一样,所以这个方法就可能出现不对应的问题,只能通过正则来获取这几个信息,因为本文主要介绍 xpath 的使用,所以正则就不贴出来了

获取评分信息

<div class="rating_self clearfix" typeof="v:Rating">
      <strong class="ll rating_num " property="v:average"> 9.0 </strong>
      <span property="v:best" content="10.0"></span>
      <div class="rating_right ">
          <div class="ll bigstar45"></div>
            <div class="rating_sum">
                <span class="">
                    <a href="collections" class="rating_people"><span property="v:votes">2010</span>人评价</a>
                </span>
            </div>
      </div>
    </div>

获取评分的方法

response.xpath('//strong[contains(@class,"rating_num")]/text()')

这边涉及到的就是 contains() 方法的使用,有时不同页面同一标签含有不同的 class 属性,就可以通过 contains 方法来进行模糊查询。
这样,整个豆瓣图书页面需要的信息就可以查询出来了

相关文章

快慢指针简单用法

快慢指针简单用法

如何避免愚蠢的见识

罗素关于如何避免有愚蠢的见识这种行为所需要的原则

Markdown 格式示例文章

Markdown 格式示例文章