推荐我的个人博客 http://blog.wuzhenyu.com.cn
scrapy 是一个用 python 语言编写的,为了爬取网站数据,提取结构性数据而编写的应用框架。
环境
本文使用的环境:
python 3.5.2
pip 9.0.1
操作系统: Ubuntu 16.04
pythton 环境搭建
在官网下载 Ubuntu 环境下的python3.5的安装包,安装,安装完成后,检查一下 python 的安装情况,一般pyhton安装的时候,pip 也是一起安装好的,如果没有安装完全,再将 pip 也一起安装好。
虚拟环境搭建
现在Ubuntu默认是安装 python2.7 的,避免两个环境之间切换的麻烦,我们安装 python 虚拟环境来解决这个问题。
pip install virtualenv
pip install virtualwrapper
pip list # 查看已安装
virtualenv 能够通过根据不同的 python 版本创建对应不同版本的虚拟环境,virtualwrapper 能够方便的在不同的虚拟环境之间进行切换。安装完成之后,下面我们创建一个 python3.5.2 版本的虚拟环境
source /usr/local/bin/virtualwrapper.sh #这个与 windows 不一样,需要先执行一下脚本才能生效,大家可以打开这个文件看一下
# 创建一个名为 py3Scrapy 的虚拟环境
mkvirtualenv py3Scrapy -p /usr/bin/python3.5
# workon 查看创建好的虚拟环境,虚拟环境的保存路径可以通过 `VIRTUALENV_PYTHON` 来配置
workon
workon py3Scrapy # 进入选择的虚拟环境
如下图所示:
python的版本也能查看得到,进入虚拟环境之后,在shell前面会出现虚拟环境的名称,退出虚拟环境
deactivate
好了,创建好环境之后,现在来开始我们的 scrapy 之旅吧。
scrapy 环境搭建
scrapy 是基于 twisted 框架的,大家会发现,安装 scrapy 的时候,会需要安装很多包。
pip install scrapy
使用 pip 进行安装,方便,但是这种默认的安装方式,实在官网下载安装包来进行安装的,比较慢,大家可以使用豆瓣源来进行安装
pip install scrapy -i https://pypi.douban.com/simple
这种方式,下载会非常的快,安装其他的包都可以使用这种方法,但是,如果使用豆瓣源安装的时候,提示找不到符合版本的安装包,那就使用第一种办法进行下载安装,因为豆瓣源可能没有官网那么及早更新。
因为每个人的环境都可能存在差异,安装过程中会出现一些问题。当如果报错,twisted 安装失败的时候,建议从官网下载 twisted 安装包,自行进行安装,安装完成之后,再接着继续上面 scrapy 的安装,安装完成之后,检查一些安装结果
scrapy -h
使用 scrapy 获取某一个文章的信息
好了,环境准备好之后,接下来我们来分析一下伯乐在线的文章网页结构
分析伯乐在线某一篇文章的网页结构和url
伯乐在线网站不需要我们先登录,然后才能访问其中的内容,所以不需要先模拟登录,直接就能访问网页。伯乐在线地址为 https://www.jobbole.com
,这上面的文章质量还是不错的,大家有时间可以看看。
我们随便找一篇文章试图来分析一下,比如 http://blog.jobbole.com/111469/
,F12进入浏览器调试窗口,从全文分析,比如我们想获取文章标题,文章内容,文章创建时间,点赞数,评论数,收藏数,文章所属类别标签,文章出处等信息
使用 scrapy shell 的方法获取解析网页数据
打开文章链接,我们获取到的是一个html页面,那么如何获取上面所说的那些数据呢,本文通过 CSS 选择器来获取(不了解 CSS selector的小伙伴可以先去熟悉一下 http://www.w3school.com.cn/cssref/css_selectors.asp
)。 scrape 为我们提供了一个 shell 的环境,可以方便我们进行调试和实验,验证我们的css 表达式能够成功获取所需要的值。下面启动 scrapy shell
scrapy shell "http://blog.jobbole.com/111469/"
scrapy 将会帮助我们将http://blog.jobbole.com/111469/
这个链接的数据捕获,现在来获取一下文章标题,在浏览器中找到文章标题,inspect element
审查元素,如下图所示:
文章标题为王垠:如何掌握所有的程序语言,从上图获知,这个位于一个 class 名为 entry-header
的 div 标签下的子标签 h1 中,那我们在 scrapy shell 通过 css 选择器来获取一下,如下图所示:
仔细查看上图,注意一些细节。通过 response.css 方法,返回的结果是一个 selector,不是字符串,在这个 selector 的基础上可以继续使用 css 选择器。通过 extract() 函数获取提取的标题内容,返回结果是一个 list,注意,这里是一个 list ,仍然不是字符串 str,使用 extract()[0] 返回列表中的第一个元素,即我们需要的标题。
但是,如果标题没有获取到,或者选择器返回的结果为空的话,使用 extract()[0] 就会出错,因为试图对一个空链表进行访问,这里使用 extract_first() 方法更加合适,可是使用一个默认值,当返回结果为空的时候,返回这个默认值
extract_first("") # 默认值为 ""
此处仅仅是将 title 标题作为一个例子进行说明,其他的就不详细进行解释了,主要代码如下所示:
title = response.css(".entry-header h1::text").extract()[0]
match_date = re.match("([0-9/]*).*",
response.css(".entry-meta-hide-on-mobile::text").extract()[0].strip())
if match_date:
create_date = match_date.group(1)
votes_css = response.css(".vote-post-up h10::text").extract_first()
if votes_css:
vote_nums = int(votes_css)
else:
vote_nums = 0
ma_fav_css = re.match(".*?(\d+).*",
response.css(".bookmark-btn::text").extract_first())
if ma_fav_css:
fav_nums = int(ma_fav_css.group(1))
else:
fav_nums = 0
ma_comments_css = re.match(".*?(\d+).*",
response.css("a[href='#article-comment'] span::text").extract_first())
if ma_comments_css:
comment_nums = int(ma_comments_css.group(1))
else:
comment_nums = 0
tag_lists_css = response.css(".entry-meta-hide-on-mobile a::text").extract()
tag_lists_css = [ele for ele in tag_lists_css if not ele.strip().endswith('评论')]
tags = ','.join(tag_lists_css)
content = response.css(".entry *::text").extract()
解释一下 create_date
,通过获取到的值,存在其他非时间的数据,通过 re.match 使用正则表达式来提取时间。
好了,所有需要的值都提取成功后,下面通过 scrapy 框架来创建我们的爬虫项目。
创建爬虫项目
开始我们的爬虫项目
scrapy startproject ArticleSpider
scrapy 会为我们创建一个名为 ArticleSpider 的项目
进入到 ArticleSpider 目录,使用basic模板创建
scrapy genspider jobbole blog.jobbole.com