Python爬虫学习记录——17.分布式爬虫

朱雀 2023-06-11 05:27 149阅读 0赞

文章目录

    • 分布式系统
    • scrapy_redis分布式
    • 实战
    • redis desktop manager软件安装及使用
    • 其他的分布式系统

分布式系统

当爬取内容过多,需要多机合作的时候,就需要用到分布式系统,这节博客讲解一下分布式爬虫的实现。

什么是分布式系统
分布式系统就是把一些计算机通过网络连接起来,然后协同工作
协同工作需要解决两个问题:

  • 任务分解
    把一个问题拆解成若干个独立任务,每个任务在一台节点上运行,实现多任务的并发执行
  • 节点通信
    节点之间互相通信,需要设计特定的通信协议来实现。协议可以采用RPC或Message Queue等方式

分布式爬虫系统

  • scrapy_redis

    • scrapy-redis是为了更方便地实现scrapy分布式爬取,而提供了一些以redis数据库为基础的组件
    • scrapy-redis提供了维持待爬取url的去重以及储存requests的指纹验证。原理是:redis维持一个共同的url队列,各个不同机器上的爬虫程序获取到的url都保存在redis的url队列,各个爬虫都从redis的url队列获取url,并把数据统一保存在同一个数据库里面
    • 本节博客主要讲授基于scrapy_redis的分布式爬虫
  • 消息队列

    • MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,消息发送后可以立即返回,由消息系统来确保消息的可靠传递
    • 它是消费-生产者模型的一个典型的代表,producer往消息队列中不断写入消息,而另一端consumer则可以读取或者订阅队列中的消息
    • 消息生产者只管把消息发布到 MQ 中而不用管谁来取,消息消费者只管从 MQ 中取消息而不管是谁发布的
  • RabbitMQ

    RabbitMQ是MQ产品的典型代表,是一款基于AMQP协议可复用的企业消息系统。业务上,可以实现服务提供者和消费者之间的数据解耦,提供高可用性的消息传输机制,在实际生产中应用相当广泛

  • scrapy_rabbitmq分布式

    Scrapy-rabbitmq-link 是可以让你从RabbitMQ 消息队列中取到URL并且分发给Scrapy spiders的组件

  • celery初步

    Celery 用消息通信,通常使用中间人(Broker)在客户端和程序间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给程序

scrapy_redis分布式

什么是Redis数据库
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库

安装Redis数据库及scrapy_redi:
这里仅介绍Windows系统下的安装

  1. 下载Redis压缩包
    前往:https://github.com/MicrosoftArchive/redis/releases
    或者前往网盘链接:http://pan.baidu.com/s/1i5f9xSL 密码:t5bo
    下载Redis-x64-3.2.100.zip,并将其解压缩
  2. 安装Redis
    打开cmd,切换到解压的文件夹下执行命令

    1. redis-server service-install redis.windows.conf loglevel verbose
  3. 启动Redis服务
    在解压的文件夹下执行命令

    1. redis-server service-start
  4. 安装scrapy_redis
    启动cmd,使用pip安装scrapy_redis

    1. pip install scrapy_redis

Scrapy_redis设置
在项目中进行如下的设置:

  • 更改去重对列必有项

    SCHEDULER = “scrapy_redis.scheduler.Scheduler”

  • 利用Redis去重:必有项

    DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter”

  • 序列化方案

    SCHEDULER_SERIALIZER = “scrapy_redis.picklecompat”

  • 故障重跑

    SCHEDULER_PERSIST = True

  • URL队列优先级

    SCHEDULER_QUEUE_CLASS = ‘scrapy_redis.queue.PriorityQueue’

  • 把item储存进Redis管道

    ITEM_PIPELINES = {
    ‘scrapy_redis.pipelines.RedisPipeline’: 300
    }

  • 队列名字

    REDIS_ITEMS_KEY = ‘%(spider)s:items’

  • 配置连接

    REDIS_HOST = ‘localhost’
    REDIS_PORT = 6379

    或者

    REDIS_URL = ‘redis://user:pass@hostname:9001’

  • 实例化一个Redis对象

    REDIS_PARAMS[‘redis_cls’] = ‘myproject.RedisClient’

  • 设置set格式(不允许重复的元素)

    REDIS_START_URLS_AS_SET = False

  • 键值对中键值命名规则

    REDIS_START_URLS_KEY = ‘%(name)s:start_urls’

  • 编码方式

    REDIS_ENCODING = ‘latin1’

启动scrapy_redis

  1. 运行爬虫:

    1. scrapy crawl 爬虫名
  2. 启动:(注意:启动的时候应该先切换到redis安装目录下)

    • url选用的是list类型:

      redis-cli lpush myspider:start_urls http://google.com

    1. url选用的是set类型:

      redis-cli sadd myspider:start_urls http://google.com

实战

这次用的依然是上节课的city58的案例,只是修改了settings.py和city58_test.py两个文件。

  1. city58_test.py:实现翻页爬取

    1. # -*- coding: utf-8 -*-
    2. import scrapy
    3. from pyquery import PyQuery
    4. from ..items import City58Item
    5. from scrapy.http import Request
    6. from scrapy_redis.spiders import RedisSpider
    7. class City58TestSpider(RedisSpider):
    8. name = 'city58_test'
    9. allowed_domains = ['58.com']
    10. start_urls = ['http://bj.58.com/chuzu/']
    11. def parse(self, response):
    12. jpy = PyQuery(response.text)
    13. li_list = jpy('body > div.mainbox > div.main > div.content > div.listBox > ul > li').items()
    14. for it in li_list:
    15. a_tag = it('div.des > h2 > a')
    16. item = City58Item()
    17. item['name'] = a_tag.text()
    18. item['url'] = (a_tag.attr('href') if a_tag.attr('href') else '')
    19. item['price'] = it('div.listliright > div.money > b').text()
    20. yield item
    21. if not li_list:
    22. return
    23. pn = response.meta.get('pn',1) #得到meta中pn的数值,如果没有,就默认为1
    24. pn += 1
    25. #response.meta['pn'] = p
    26. if pn > 5
    27. return
    28. #把相对路径转化为绝对路径,并request访问
    29. req = response.follow('/chuzu/pn{}/'.format(pn), #拼接相对路径
    30. callback = self.parse,
    31. meta = { 'pn':pn} #使用meta参数进行传值
    32. )
    33. yield req
  2. settings.py

    1. SCHEDULER = "scrapy_redis.scheduler.Scheduler" #必有项:更改去重对列
    2. # Ensure all spiders share same duplicates filter through redis.
    3. DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" #必有项:利用Redis去重
    4. #SCHEDULER_PERSIST = True #故障重跑
    5. REDIS_URL = 'redis://localhost:6379' #配置连接
    6. #REDIS_START_URLS_AS_SET = False #设置set格式(不允许重复的元素)
  3. 运行时要记得在队列中塞入start_urls

    1. redis-cli lpush city58_test:start_urls http://bj.58.com

redis desktop manager软件安装及使用

  1. Windows系统安装包下载
    前往网盘链接:http://pan.baidu.com/s/1gfpgQxt 密码:iz9u
  2. 根据提示进行安装
    只需要执行默认安装便可
  3. 打开软件,点击connect to redis server
  4. 输入数据库名字,以及host和端口
    数据库名字test,host为127.0.0.1(本机),默认端口为6379
  5. 打开数据库,就可以看到数据了

其他的分布式系统

本篇博客介绍了基于scrapy-redis的分布式系统,用于分布式爬虫URL队列的存储和去重队列的存储。当然,对于更大型的爬虫系统,或者对于非scrapy框架的爬虫,可以选择其它的方案替代scrapy和scrapy-redis,比如可以使用RabbitMQ消息队列代替Redis。以下的内容,提供了更多关于分布式爬虫的知识和方案

  • 消息队列
    MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,它是消费-生产者模型的一个典型的代表,producer往消息队列中不断写入消息,而另一端consumer则可以读取或者订阅队列中的消息

    爬虫之消息队列
    在构建一个松耦合或是异步的系统时,消息队列是最常用的方法。在爬虫中使用消息队列有哪些好处呢?

    • 通过消息队列实现线程安全的去重
    • 多进程消费爬虫任务队列
    • 确保每一条任务都执行

    RabbitMQ消息队列
    RabbitMQ 是一种消息队列,用于程序间的通信
    形象地说 : MQ就像一个邮局,发送者将消息写入 MQ,MQ 负责把消息发送给接收者。RabbitMQ 可支持 Java, PHP, Python, Go, JavaScript, Ruby 等多种语言
    在这里插入图片描述
    注意:RabbitMQ的使用需要事先安装
    Scrapy-rabbitmq-link的安装和配置
    Scrapy-rabbitmq-link 是可以让你从RabbitMQ 消息队列中取到URL并且分发给Scrapy spiders的组件

    • 安装:

      pip install scrapy-rabbitmq-link

    • 配置:

      Enable RabbitMQ scheduler

      SCHEDULER = “scrapy_rabbitmq_link.scheduler.SaaS”

      Provide AMQP connection string

      RABBITMQ_CONNECTION_PARAMETERS = ‘amqp://guest:guest@localhost:5672/‘

      Set response status codes to requeue messages on

      SCHEDULER_REQUEUE_ON_STATUS = [500]

      Middleware acks RabbitMQ message on success

      DOWNLOADER_MIDDLEWARES = {

      1. 'scrapy_rabbitmq_link.middleware.RabbitMQMiddleware': 999

      }

  • Celery - 分布式任务队列
    Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具

    它是一个专注于实时处理的任务队列,同时也支持任务调度

    Celery 需要一个发送和接受消息的传输者。Celery 支持 RabbitMQ、Redis 甚至其他数据库系统作为其消息代理中间件,但也提供大量其他实验性方案的支持

    Celery 好处也很多,尤其在使用python构建的应用系统中,无缝衔接,使用相当方便

    celery的应用场景

    • 处理异步任务
    • 任务调度
    • 处理定时任务
    • 分布式调度
    • 安装Celery

    安装Celery

    1. pip install celery

    配置Celery

    1. from celery import Celery
    2. app = Celery('hello', broker='amqp://guest@localhost//') #配置rabbitMQ
    3. @app.task #装饰器
    4. def hello():
    5. return 'hello world'

发表评论

表情:
评论列表 (有 0 条评论,149人围观)

还没有评论,来说两句吧...

相关阅读

    相关 爬虫--分布式爬虫

    爬虫的本质:   很多搞爬虫的总爱吹嘘分布式爬虫,仿佛只有分布式才有逼格,不是分布式简直不配叫爬虫,这是一种很肤浅的思想。   分布式只是提高爬虫功能和效率的一个环节而已,

    相关 Python爬虫学习

    网络爬虫是一种互联网机器人,它通过爬取互联网上网站的内容来工作。它是用计算机语言编写的程序或脚本,用于自动从Internet上获取任何信息或数据。机器人扫描并抓取每个所需页面上