0
点赞
收藏
分享

微信扫一扫

【Scrapy教程】02 Xpath选择器


前言

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

border="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=4874559&auto=1&height=66">

Xpath

什么是xpath?

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

xpath节点关系

现在有一段代码(伯乐在线的):

【Scrapy教程】02 Xpath选择器_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/​​

【Scrapy教程】02 Xpath选择器_html_02


先抽取任意一篇文章进行分析,分析伯乐在线的html代码,抓取我们需要的信息:标题、时间、点赞数、收藏数。。。等等以标题为例子:

​linus定义linux​

【Scrapy教程】02 Xpath选择器_笔记_03


可以看到此处的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​​)的选项,如下图:

【Scrapy教程】02 Xpath选择器_html_04

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

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


举报

相关推荐

0 条评论