【Scrapy教程】02 Xpath选择器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/s740556472/article/details/81023624

前言

继续上一章的学习笔记,scrapy中常用到的两种抓取数据的方式,一个是CSS选择器,一个是XPATH选择器。而本章先介绍其中之一,xpath选择器。
music:

Xpath

什么是xpath?

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

xpath节点关系

现在有一段代码(伯乐在线的):
这里写图片描述

节点的概念

所谓的节点,就是向上面代码所看到的,像<head>,<title>,<meta>这样的标签..

而诸多标签形成了如下的关系:

  1. 父节点
  2. 子节点
  3. 同胞节点
  4. 先辈节点
  5. 后代节点

① 父节点:head就是title的父节点
②子节点:title就是head的子节点
③同胞节点:head下,有两个同级的meta节点,而这两个meta就是同胞节点
④先辈节点:head就是title的父节点,也是title的先辈节点,而html又是head的父节点,所以html也是title的先辈节点。
⑤后代节点:与先辈节点相反,也就是子孙节点,都可以认为是后代节点,比如html下的head,title节点,都是后代节点。

属性的概念

在说明之前,要明白一个词属性

<input id = "article" name = "article" />

这里的id,name就是属性,而article是他们的值。

xpath语法

有了上面的概念,接下来就可以了解xpath表达式的语法了,假设我们有一个名为article的元素节点:

表达式 说明
article 选取所有article元素的所有子节点
/article 选取根元素(在页面上,根元素一般是html节点)article
article/a 选取所有属于article的子元素(一定是子元素)的a元素
//div 选取所有(html里的)div子元素(不论出现在文档的任何地方)
article//div 选取所有属于article元素的后代的div元素,不管它出现在article之下的任何地方
//@class 选取所有名为class的属性(@代表某个元素的class属性)
//span|//ul 选取文档中的span和ul元素(|代表并集,和)

xpath语法 - 谓语

表达式 说明
/article/div[1] 选取属于article子元素的第一个div元素(写法:div[1])
/article/div[last()] 选取属于article子元素的最后一个div元素(写法:div[last())
/article/div[last()-1] 选取属于article子元素的倒数第二个div元素(写法:div[last()-1)
//div[@lang] 选取所有拥有lang属性的div元素
//div[@lang=’eng’] 选取所有拥有lang属性的为eng的div元素 (***重要常用***)

scrapy中的用法

打开伯乐在线首页,我们可以发现有一处拥有所有文章地址:
http://blog.jobbole.com/all-posts/
这里写图片描述
先抽取任意一篇文章进行分析,分析伯乐在线的html代码,抓取我们需要的信息:标题、时间、点赞数、收藏数。。。等等

以标题为例子:
linus定义linux
这里写图片描述
可以看到此处的div的class属性值为entry-header,此时可以如下写到:

class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    # start_urls = ['http://blog.jobbole.com/']
    start_urls = ['http://blog.jobbole.com/all-posts/']

    def parse(self, response):
        """
        response是scrapy服务端响应的对象,调用extract方法可以提取
        对应xpath响应的列表,但是提取第一个元素可以用[0],有一点弊端:
        用[0],若不存在第一个元素则会报错,在css选择器中会总结另一种提
        取方法....
        """
        # 标题
        article_title = response.xpath('//div[@class="entry-header"]/h1/text()').extract()[0]

在抓取伯乐实战中,scrapy用到的代码如下:

""" --------------    xpath 案例 start    --------------"""
# 标题
article_title = response.xpath('//div[@class="entry-header"]/h1/text()').extract()[0]
print(article_title)

# 时间
article_time = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].strip().replace(
    '·', '').strip()

print(article_time)
# 点赞数
article_praise = response.xpath('//span[contains(@class,"vote-post-up")]/h10/text()').extract()[0]
print(article_praise)

# 收藏数
bookmark = response.xpath('//span[contains(@class,"bookmark-btn")]/text()').extract()[0]
# 正则提取收藏数字
match_bookmark = re.match('.*(\d+).*', bookmark)
if match_bookmark:
    article_bookmark = match_bookmark.group(1)
    print(article_bookmark)

# 评论数
comments = response.xpath('//a[@href="#article-comment"]/text()').extract()[0]
match_comments = re.match('.*(\d+).*', comments)
if match_comments:
    article_comments = match_comments.group(1)
    print(article_comments)

# 文章详情
article_contents = response.xpath('//div[@class="entry"]').extract()[0]

# 文章标签
tag_list = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/a/text()').extract()

# 去重标签
tag_list = [element for element in tag_list if not element.strip().endswith("评论")]
tags = ','.join(tag_list)
print(tags)
"""--------------    xpath 案例 end    --------------"""

心得与tips

现在的浏览器都很强大,因为像谷歌,火狐这类浏览器自带了html的css和xpath复制功能,只需要F12打开开发者模式,然后选择你需要的标签属性,右键copy,便有各种css(cpoy selector)或者xpath(copy xpath)的选项,如下图:
这里写图片描述

当然,了解xpath语法对于我们学习来说是一件好事儿,毕竟熟能生巧,万一有一天遇到了像IE这样的浏览器,真的要哭了,因为楼主自己亲身体验过。。也正是因为IE没有这么强大的copy as功能,才对xpath略有了一丝熟悉。。


今日总结就到这里了,下一篇总结css选择器的使用。。!

猜你喜欢

转载自blog.csdn.net/s740556472/article/details/81023624