首页 > 其他 > 详细

scrapy-redis实现分布式爬虫

时间:2020-08-07 09:48:28      阅读:77      评论:0      收藏:0      [点我收藏+]

一 介绍

原来scrapy的Scheduler维护的是本机的任务队列(存放Request对象及其回调函数等信息)+本机的去重队列(存放访问过的url地址)

技术分享图片

 

 所以实现分布式爬取的关键就是,找一台专门的主机上运行一个共享的队列比如Redis,
然后重写Scrapy的Scheduler,让新的Scheduler到共享队列存取Request,并且去除重复的Request请求,所以总结下来,实现分布式的关键就是三点:

#1、共享队列
#2、重写Scheduler,让其无论是去重还是任务都去访问共享队列
#3、为Scheduler定制去重规则(利用redis的集合类型)

以上三点便是scrapy-redis组件的核心功能

技术分享图片

 

 

#安装:
pip3 install scrapy-redis

#源码:
D:\python3.6\Lib\site-packages\scrapy_redis

二、scrapy-redis组件

使用分布式爬虫步骤

1、安装

# pip3 install scrapy-redis

2、爬虫继承RedisSpider,(原来继承Spider)

import scrapy
from cnblogs.items import CnblogsMysqlItem
from scrapy_redis.spiders import RedisSpider


class CnblogSpider(RedisSpider):
    name = cnblog
    allowed_domains = [www.cnblogs.com]
    redis_key = myspider:start_urls
    # start_urls = [‘http://www.cnblogs.com/‘]

    def parse(self, response):
        # 爬取cnblogs文章,把标题连接地址和文章内容保存到mysql,连续爬取n页
        article_list = response.css(.post-item)
        for article in article_list:
            item = CnblogsMysqlItem()
            title = article.css(.post-item-title::text).extract_first()
            title_url = article.css(.post-item-title::attr(href)).extract_first()
            summary = article.css(.post-item-summary::text).extract_first()
            # 将解析到的数据封装至items对象中,注意:不支持item.title = title方式
            item[title] = title
            item[title_url] = title_url
            item[summary] = summary
            # 要继续爬取详情
            # callback如果不写,默认回调到parse方法
            # 如果写了,响应回来的对象就会调到自己写的解析方法中
            # meta将参数传到回调函数
            yield scrapy.Request(title_url, callback=self.parser_detail, meta={item: item})

        # 查找当前页是否存在下一页
        pager = response.xpath(//div[@class="pager"])
        next_page = pager.xpath(.//a[last()]/text()).extract_first()
        # print(next_page)
        if next_page is ">":
            next_page_url = pager.xpath(.//a[last()]/@href).extract_first()
            next_page_url_full = https://www.cnblogs.com%s % next_page_url
            print(next_page_url_full)
            yield scrapy.Request(next_page_url_full, callback=self.parse)
            # yield scrapy.Request(next_page_url_full, callback=self.parse)

    def parser_detail(self, response):

        item = response.meta.get(item)

        # item哪里来
        content = response.css(#cnblogs_post_body).extract_first()
        item[content] = content
        print(item)
        yield item

3、不能写start_urls,需要写redis_key,具体见2

4、setting中配置:

# 使用scrapy-redis的去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 使用scrapy-redis的Scheduler
# 分布式爬虫的配置
SCHEDULER = "scrapy_redis.scheduler.Scheduler"


# 持久化的可以配置,也可以不配置
# 开启管道
ITEM_PIPELINES = {
    # ‘cnblogs.pipelines.CnblogsFilePipeline‘: 300,
    cnblogs.pipelines.CnblogsMysqlPipeline: 305,
    scrapy_redis.pipelines.RedisPipeline: 299
}

# 默认scrapy-redis链接redis是127.0.0.1:6379,如果想改见下面配置
REDIS_HOST = localhost                            # 主机名
REDIS_PORT = 6379                                   # 端口
#REDIS_PASS = ‘redisP@ssw0rd‘                 # 密码
REDIS_URL = redis://user:pass@hostname:9001       # 连接URL(优先于上面三行配置)
REDIS_PARAMS  = {}                                  # Redis连接参数
REDIS_PARAMS[redis_cls] = myproject.RedisClient # 指定连接Redis的Python模块
REDIS_ENCODING = "utf-8"                            # redis编码类型 

示例启动三个进程演示:

技术分享图片

5、现在要让爬虫运行起来,需要去redis中以myspider:start_urls为key,插入一个起始地址

# lpush myspider:start_urls https://www.cnblogs.com/

 

scrapy-redis实现分布式爬虫

原文:https://www.cnblogs.com/baicai37/p/13449950.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!