爬虫提高:scrapy_redis
scrapy_redis 是什么#
Scrapy_redis : Redis-based components for Scrapy.
Github 地址:github.com/rmax/scrapy-redis
为什么要学习 scrapy_redis#
Scrapy_redis 在 scrapy 的基础上实现了更多,更强大的功能,具体体现在:
- 请求对象的持久化
- 去重的持久化
- 和实现分布式
scrapy_redis 的原理分析#
scrapy_redis 的流程#
- 在 scrapy_redis 中,所有的带抓取的对象和去重的指纹都存在所有的服务器公用的 redis 中
- 所有的服务器公用一个 redis 中的 request 对象
- 所有的 request 对象存入 redis 前,都会在同一个 redis 中进行判断,之前是否已经存入过
- 在默认情况下所有的数据会保存在 redis 中
redis 的复习#
redis 是什么#
redis 是一个开源的内存型数据库,支持多种数据类型和结构,比如列表、集合、有序集合等
redis 服务端和客户端的启动#
/etc/init.d/redis-server start
启动服务端redis-cli -h <hostname> -p <端口号>
客户端启动
redis 中的常见命令#
select 1
切换 dbkeys *
查看所有的键tyep 键
查看键的类型flushdb
清空 dbflushall
清空数据库
scrapy_redis domz 爬虫分析#
拷贝源码中的 demo 文件#
1、clone github scrapy-redis 源码文件 git clone https://github.com/rolando/scrapy-redis.git
2、研究项目自带的三个 demo mv scrapy-redis/example-project ~/scrapyredis-project
观察 dmoz 文件#
在 domz 爬虫文件中,实现方式就是之前的 crawlspider
类型的爬虫
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class DmozSpider(CrawlSpider):
"""Follow categories and extract links."""
name = 'dmoz'
allowed_domains = ['dmoztools.net']
start_urls = ['http://dmoztools.net/']
# 定义数据提取规则,使用了css选择器
rules = [
Rule(LinkExtractor(
restrict_css=('.top-cat', '.sub-cat', '.cat-item')
), callback='parse_directory', follow=True),
]
def parse_directory(self, response):
for div in response.css('.title-and-desc'):
yield {
'name': div.css('.site-title::text').extract_first(),
'description': div.css('.site-descr::text').extract_first().strip(),
'link': div.css('a::attr(href)').extract_first(),
}
但是在 settings.py 中多了一下几行,这几行表示 scrapy_redis
中重新实现的了去重的类,以及调度器,并且使用的 RedisPipeline
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
ITEM_PIPELINES = {
'example.pipelines.ExamplePipeline': 300,
'scrapy_redis.pipelines.RedisPipeline': 400,
}
运行 dmoz 爬虫,观察现象#
首先我们需要添加 redis 的地址,程序才能够使用 redis
REDIS_URL = "redis://127.0.0.1:6379"
#或者使用下面的方式
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
我们执行 domz 的爬虫,会发现 redis 中多了一下三个键
继续执行程序,会发现程序在前一次的基础之上继续往后执行,所以 domz 爬虫是一个基于 url 地址的增量式的爬虫
scrapy_redis 的原理分析#
我们从 settings.py 中的三个配置来进行分析 分别是:
- RedisPipeline
- RFPDupeFilter
- Scheduler
Scrapy_redis 之 RedisPipeline#
RedisPipeline 中观察 process_item,进行数据的保存,存入了 redis 中
Scrapy_redis 之 RFPDupeFilter#
RFPDupeFilter 实现了对 request 对象的加密
Scrapy_redis 之 Scheduler#
scrapy_redis 调度器的实现了决定什么时候把 request 对象加入带抓取的队列,同时把请求过的 request 对象过滤掉
由此可以总结出 request 对象入队的条件
- request 之前没有见过
- request 的 dont_filter 为 True,即不过滤
- start_urls 中的 url 地址会入队,因为他们默认是不过滤
scrapy_redis 实现分布式爬虫#
RedisSpider#
分析 demo 中代码#
通过观察代码:
- 继承自父类为 RedisSpider
- 增加了一个 redis_key 的键,没有 start_urls,因为分布式中,如果每台电脑都请求一次 start_url 就会重复
- 多了
__init__
方法,该方法不是必须的,可以手动指定 allow_domains
RedisCrawlSpider#
分析 demo 中的代码#
和 scrapy 中的 crawlspider 的区别在于,继承自的父类不想听,redis_key 需要添加
crontab 爬虫定时启动#
安装#
命令:apt-get install cron
使用#
命令:crontab -e 进入编辑页面(第一次会让你选择编辑器)
crontab -l
查看当前的定时任务
编辑:
分 小时 日 月 星期 命令
0-59 0-23 1-31 1-12 0-6 command
注意点:
1. 星期中 0 表示周日
2. 每隔两个小时的时候前面的不能为 *
,为 *
表示每分钟都会执行
crontab 在爬虫中的使用#
使用流程#
- 把爬虫启动命令写入
.sh
文件 - 给
.sh
脚本添加可执行权限 - 把
.sh
添加到 crontab 脚本正
myspier.sh 例子#
执行命令写入脚本
其中 >>
表示重定向,把 print 等信息导入 log 中
2>&1
表示把标准错误作为标准输出,输入用 0 表示,标准输出用 1 表示,标准错误用 2 标识,通过该命令能够把错误一起输出到 log 中
cd `dirname $0` || exit 1
python ./main.py >> run.log 2>&1
添加可执行权限
sudo chmod +x myspder.sh
写入 crontab 中
sh 脚本文件也可能会报错,对应的可以把其输出和错误重定向到 run2.log 中
0 6 * * * /home/ubuntu/..../myspider.sh >> /home/ubuntu/.../run2.log 2>&1
推荐文章: