分布式爬虫

分布式爬虫

  • 实现方式:scrapy+redis(scrapy结合这scrapy-redis组件)
  • 原生的scrapy框架是无法实现分布式
    • 需要搭建一个分布式的机群,让后让机群中的每一台电脑执行同一组程序,让其对同一组资源 进行联合且分布的数据爬取。
    • 为什么原生的scrapy框架无法实现分布式
      • 1.调度器无法被分布式机群共享
      • 2.管道无法被分布式机群共享
    • scrapy-redis组件的作用:
      • 可以给原生的scrapy框架提供共享的管道和调度器
      • pip install scrapy-redis

步骤

1.修改爬虫文件

-1.1导包from scrapy_redis.spiders import RedisCrawlSpider

-1.2将源文件中的父类修改成RedisCrawlSpider

-1.3将start_url替换成redis_keys的属性,属性值为任意字符

- redis_key = 'xxx':表示的是可以被共享的调度器队列的名称,最终是需要将起始的url手动放置到		redis_key表示的队列中,所以start_url都注释了,后续需要在redis中输入网址即可

-1.4将数据解析完整即可

2.对settings.py进行配置

  • 指定调度器

    • 增加一个去重容器类的配置,作用使用Redis的set集合来存储请求的指纹数据,从而实现请求去重的持久化

    • 直接将以下三个配置放到settings中(复制粘贴即可)

       # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
                  DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
                  # 使用scrapy-redis组件自己的调度器
                  SCHEDULER = "scrapy_redis.scheduler.Scheduler"
                  # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
                  SCHEDULER_PERSIST = True
      
  • 指定管道(复制粘贴到settings中,不可以自定义,封装好的)

    • ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 400 }
      • 特点:该种管道只可以将item写入redis,(这里补充一下redis,他不能存储大文件,他是内存数据库,就算持久化他也是断电之前将数据存储在本地,然后开机就将数据加载到内存中)
  • 指定redis

    • REDIS_HOST = 'redis服务的ip地址' (由于测试使用127.0.0.1的,将来使用真实的redis所在的ip地址)

    • REDIS_PORT = 6379

    • # REDIS_ENCODING = ‘utf-8’
      # REDIS_PARAMS = {‘password’:’123456’}
      将来redis如果有账号密码加上这个配置
      

    3.配置redis的配置文件(redis.window.conf)

    • 解除默认绑定 (意思就是允许其他ip地址的客户端远程访问)
      • 56行:#bind 127.0.0.1

  • 关闭保护模式() (保护模式就是别的客户端只能读数据,不能写数据。关闭就远程客户端可以写数据了)

    -75行:protected-mode no (将yes改成no)

4.启动redis服务和客户端

5.执行scrapy工程(不要在配置文件中加入LOG_LEVEL)

启动之后你会发现项目在监听,在等,等传入起始的url加入

6.向redis_key表示的队列中添加起始url

当初咱们在spider源文件中写了redis_key了

需要在redis的客户端执行如下指令:(调度器队列是存在于redis中)

lpush sunQueue http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1

lpush 将起始的url就是你想爬取的url扔进去,没有此key会自动创建,不用担心,sunQueue千万别忘了是你的队列名字,你起的什么 就些什么

!!!当你输入完这句话后,你就会看到监听的终端会开始下载了

好的体验就是将settings中的线程数改小一点,假如你是32线程,当其他人的电脑配置特别低的话,就是调度器发布任务,抢不到资源,他就不干活了,所以你最好设置低一点的线程,当你的线程都在执行,别人电脑配置在低也能抢到资源,当然这个只是为了看效果,但是实战的时候不要将线程数改的特别低!!!!

spider源文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider
from fbs_project.items import FbsProjectItem
class TestSpider(RedisCrawlSpider):
    name = 'test'
    # allowed_domains = ['www.xxxx.com']
    # start_urls = ['http://www.xxxx.com/']
    redis_key='sunQueue' #可以被共享的调度器队列的名称
    #稍后我们是需要将一个起始的url手动的添加到redis_key表示的队列中

    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:
            title = li.xpath('./span[3]/a/text()').extract_first()
            item = FbsProjectItem()
            item['title'] = title
            yield item

posted @ 2020-04-13 23:24  zz洲神在此  阅读(45)  评论(0编辑  收藏