在写爬虫的过程中,难免要和HTML DOM节点打交道,xpath就是一门优秀的查找遍历HTML节点的语法,通过分析豆瓣图书页面 重构 来掌握xpath的所有语法和功能
首先,通过爬虫爬取了页面的选择器 response(这部分内容可通过查看 scrapy入门 来获取更多信息),接下来,就可以尝试获取页面的内容了
查找获取书名
在页面元素中找到书名所在的节点
<h1>
<span property="v:itemreviewed">重构</span>
<div class="clear"></div>
</h1>
因为这个节点没有特定的 class
或 id
属性,所以我们只能通过 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
方法来进行模糊查询。
这样,整个豆瓣图书页面需要的信息就可以查询出来了