爬虫提高: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 中的常见命令#

  1. select 1 切换 db
  2. keys * 查看所有的键
  3. tyep 键 查看键的类型
  4. flushdb 清空 db
  5. flushall 清空数据库

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 在爬虫中的使用#

使用流程#

  1. 把爬虫启动命令写入.sh 文件
  2. .sh 脚本添加可执行权限
  3. .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

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~