scrapy框架之分布式爬虫

  • 概念:我们需要搭建一个分布式的机群,让其对一组资源进行分布联合爬取
    • 作用:提升爬取数据的效率
    • 如何实现分布式?
      • 安装一个scrapy-redis的组件(使用的是redis数据库)
      • 原生的scrapy是不可以实现分布式爬虫的,必须让scrapy结合着scrapy-redis组件一起实现分布式爬虫
      • 为什么原生的scrapy框架不能实现分布式爬虫 ?
        • 1.调度器不可以被分布式机群共享
          2.管道不可以被分布式机群共享
      • scrapy-redis组件作用:
        • 可以给原生的scrapy框架提供可以共享的调度器和管道
      • 实现流程:
        • 创建一个工程
        • 创建基于CrawlSpider的爬虫文件
        • 修改当前的爬虫文件:
          • 导包:from scrapy_redis.spiders import RedisCrawlSpider
          • 将start_urls和allowed_domins进行注释
          • 添加一个新属性:redis_key = ‘sun’ 即可以被共享的调度器队列的名称
          • 编写数据解析相关操作
          • 将当前爬虫类的父类修改成RedisCrawlSpider
        • 修改配置文件settings
          • 指定使用可以被共享的管道(死的,可以直接复制)
            ITEM_PIPELINES = {
            ‘scrapy_redis.pipelines.RedisPipeline’: 400,
            }
          • 指定可以共享的调度器(死的,可以直接复制)
            #增加了一个去重容器类的配置,作用 使用Redis的set集合来存储请求的指纹数据,
            从而实现请求去重的持久化
            DUPEFILTER_CLASS =“scrapy_redis.dupefilter.RFPDupeFilter”
            #使用scrapy_redis组件自己的调度器
            SCHEDULER = “scrapy_redis.scheduler.Scheduler”
            #配置调度器是否要持久化,也就是当爬虫结束了,要不要清空Redis中请求队列和去重指纹的
            set。如果是True,不清空,即只爬取没有爬到的数据,爬过的就不爬了
            SCHEDULER_PERSIST=True
          • 指定resid服务器:
            REDIS_HOST=‘redis远程服务器的IP(自行修改)’
            REDIS_PORT=‘端口号’
        • redis相关操作设置:(安装可参考菜鸟教程)
          • 配置redis的配置文件:
            • Linux或者mac:redis.conf
            • Windows:redis.windows.conf
            • 打开配置文件修改(vi redis.windows.conf)(Windows直接记事本修改):
              • 将 bind 127.0.0.1删除
              • 关闭保护模式:protected-mode yes改为no
          • 结合着配置文件开启redis服务
            • redis_server 配置文件(redis.windows.conf)
          • 启动客户端
            • redis_cli.exe
          • 执行工程(进入到spiders目录下)
            • scrapy runspider xxx.py
          • 向调度器的队列中放入一个起始url:
            • 调度器的队列在redis客户端中
              • lpush xxx(队列名称) www.xxx.com
          • 爬取到的数据存储在了redis的proName:items这个数据结构中

其实分布式的代码并不难,主要是配置比较费时,下面代码参考前一篇博客。

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from fenbushipro.items import FenbushiproItem
class FbsSpider(RedisCrawlSpider):
    name = 'fbs'
    # allowed_domains = ['www.xxx.com']
    # start_urls = ['http://www.xxx.com/']
    redis_key = 'sun'
    rules = (
        Rule(LinkExtractor(allow=r'id=1&page=\d+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')
        for li in li_list:
            new_num = li.xpath('/html/body/div[2]/div[3]/ul[2]/li[1]/span[1]/text()').extract_first()
            new_title = li.xpath('/html/body/div[2]/div[3]/ul[2]/li[1]/span[3]/a/text()').extract_first()
            print(new_num,new_title)  #用于测试程序是否出错
            item = FenbushiproItem()
            item['new_num'] = new_num
            item['new_title'] = new_title
            yield item

ITEM_PIPELINES = {
    
    
        'scrapy_redis.pipelines.RedisPipeline': 300,
        }
#指定可以共享的调度器
#增加了一个去重容器类的配置,作用 使用Redis的set集合来存储请求的指纹数据,
#从而实现请求去重的持久化
DUPEFILTER_CLASS ="scrapy_redis.dupefilter.RFPDupeFilter"
#使用scrapy_redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#配置调度器是否要持久化,也就是当爬虫结束了,要不要清空Redis中请求队列和去重指纹的
#set。如果是True,不清空
SCHEDULER_PERSIST=True
#指定服务器
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379

猜你喜欢

转载自blog.csdn.net/qwerty1372431588/article/details/107303456
今日推荐