Scrapy-Redis分布式爬虫

介绍

  1. scrapy-redis巧妙的利用redis 实现 request queue items queue,利用redisset实现request的去重,将scrapy从单台机器扩展多台机器,实现较大规模的爬虫集群
  1. scrapy-redis是基于redisscrapy组件
  2. 分布式爬虫
  3. 多个爬虫实例分享一个redis request队列,非常适合大范围多域名的爬虫集群
  4. 分布式后处理
  5. 爬虫抓取到的items push到一个redis items队列,这就意味着可以开启多个items processes来处理抓取到的数据,比如存储到MongodbMysql
  6. 基于scrapy即插即用组件
  7. Scheduler + Duplication Filter, Item Pipeline, Base Spiders.

scrapy-redis架构

• 调度器(Scheduler)

  1. scrapy-redis调度器通过redisset不重复的特性,实现了Duplication Filter去重(DupeFilter set存放爬取过的request)。
  2. Spider新生成的request,将request的指纹到redisDupeFilter set检查是否重复,并将不重复的request push写入redisrequest队列。
  3. 调度器每次从redisrequest队列里根据优先级pop出一个request, 将此request发给spider处理。

• Item Pipeline

  1. Spider爬取到的Itemscrapy-redisItem Pipeline,将爬取到的Item存入redisitems队列。可以很方便的从items队列中提取item,从而实现items processes 集群

scrapy - redis安装与使用

安装scrapy-redis

之前已经装过scrapy了,这里直接装scrapy-redis

  1. pip install scrapy-redis

使用scrapy-redis的example来修改

先从github上拿到scrapy-redis的example,然后将里面的example-project目录移到指定的地址

  1. git clone https://github.com/rolando/scrapy-redis.git
  2. cp -r scrapy-redis/example-project ./scrapy-youyuan

或者将整个项目下载回来scrapy-redis-master.zip解压后

  1. cp -r scrapy-redis-master/example-project/ ./redis-youyuan
  2. cd redis-youyuan/

tree查看项目目录

修改settings.py

注意:settings里面的中文注释会报错,换成英文

  1. # 指定使用scrapy-redis的Scheduler
  2. SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  3. # 在redis中保持scrapy-redis用到的各个队列,从而允许暂停和暂停后恢复
  4. SCHEDULER_PERSIST = True
  5. # 指定排序爬取地址时使用的队列,默认是按照优先级排序
  6. SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue'
  7. # 可选的先进先出排序
  8. # SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderQueue'
  9. # 可选的后进先出排序
  10. # SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack'
  11. # 只在使用SpiderQueue或者SpiderStack是有效的参数,,指定爬虫关闭的最大空闲时间
  12. SCHEDULER_IDLE_BEFORE_CLOSE = 10
  13. # 指定RedisPipeline用以在redis中保存item
  14. ITEM_PIPELINES = {
  15. 'example.pipelines.ExamplePipeline': 300,
  16. 'scrapy_redis.pipelines.RedisPipeline': 400
  17. }
  18. # 指定redis的连接参数
  19. # REDIS_PASS是我自己加上的redis连接密码,需要简单修改scrapy-redis的源代码以支持使用密码连接redis
  20. REDIS_HOST = '127.0.0.1'
  21. REDIS_PORT = 6379
  22. # Custom redis client parameters (i.e.: socket timeout, etc.)
  23. REDIS_PARAMS = {}
  24. #REDIS_URL = 'redis://user:pass@hostname:9001'
  25. #REDIS_PARAMS['password'] = 'itcast.cn'
  26. LOG_LEVEL = 'DEBUG'
  27. DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'
  28. #The class used to detect and filter duplicate requests.
  29. #The default (RFPDupeFilter) filters based on request fingerprint using the scrapy.utils.request.request_fingerprint function. In order to change the way duplicates are checked you could subclass RFPDupeFilter and override its request_fingerprint method. This method should accept scrapy Request object and return its fingerprint (a string).
  30. #By default, RFPDupeFilter only logs the first duplicate request. Setting DUPEFILTER_DEBUG to True will make it log all duplicate requests.
  31. DUPEFILTER_DEBUG =True
  32. # Override the default request headers:
  33. DEFAULT_REQUEST_HEADERS = {
  34. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  35. 'Accept-Language': 'zh-CN,zh;q=0.8',
  36. 'Connection': 'keep-alive',
  37. 'Accept-Encoding': 'gzip, deflate, sdch',
  38. }

查看pipeline.py

  1. from datetime import datetime
  2. class ExamplePipeline(object):
  3. def process_item(self, item, spider):
  4. item["crawled"] = datetime.utcnow()
  5. item["spider"] = spider.name
  6. return item

流程

  1. - 概念:可以使用多台电脑组件一个分布式机群,让其执行同一组程序,对同一组网络资源进行联合爬取。
  2. - 原生的scrapy是无法实现分布式
  3. - 调度器无法被共享
  4. - 管道无法被共享
  5. - 基于scrapy+redisscrapy&scrapy-redis组件)实现分布式
  6. - scrapy-redis组件作用:
  7. - 提供可被共享的管道和调度器
  8. - 环境安装:
  9. - pip install scrapy-redis
  10. - 编码流程:
  11. 1.创建工程
  12. 2.cd proName
  13. 3.创建crawlspider的爬虫文件
  14. 4.修改一下爬虫类:
  15. - 导包:from scrapy_redis.spiders import RedisCrawlSpider
  16. - 修改当前爬虫类的父类:RedisCrawlSpider
  17. - allowed_domainsstart_urls删除
  18. - 添加一个新属性:redis_key = 'xxxx'可以被共享的调度器队列的名称
  19. 5.修改配置settings.py
  20. - 指定管道
  21. ITEM_PIPELINES = {
  22. 'scrapy_redis.pipelines.RedisPipeline': 400
  23. }
  24. - 指定调度器
  25. # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
  26. DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
  27. # 使用scrapy-redis组件自己的调度器
  28. SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  29. # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
  30. SCHEDULER_PERSIST = True
  31. - 指定redis数据库
  32. REDIS_HOST = 'redis服务的ip地址'
  33. REDIS_PORT = 6379
  34. 6.配置redis数据库(redis.windows.conf
  35. - 关闭默认绑定
  36. - 56Line:#bind 127.0.0.1
  37. - 关闭保护模式
  38. - 75lineprotected-mode no
  39. 7.启动redis服务(携带配置文件)和客户端
  40. - redis-server.exe redis.windows.conf
  41. - redis-cli
  42. 8.执行工程
  43. - scrapy runspider spider.py
  44. 9.将起始的url仍入到可以被共享的调度器的队列(sun)中
  45. - redis-cli中操作:lpush sun www.xxx.com
  46. 10.redis:
  47. - xxx:items:存储的就是爬取到的数据

分布式爬取案例

爬虫程序

  1. # -*- coding: utf-8 -*-
  2. import scrapy
  3. from scrapy.linkextractors import LinkExtractor
  4. from scrapy.spiders import CrawlSpider, Rule
  5. from scrapy_redis.spiders import RedisCrawlSpider
  6. from fbs.items import FbsproItem
  7. class FbsSpider(RedisCrawlSpider):
  8. name = 'fbs_obj'
  9. # allowed_domains = ['www.xxx.com']
  10. # start_urls = ['http://www.xxx.com/']
  11. redis_key = 'sun'#可以被共享的调度器队列的名称
  12. link = LinkExtractor(allow=r'type=4&page=\d+')
  13. rules = (
  14. Rule(link, callback='parse_item', follow=True),
  15. )
  16. print(123)
  17. def parse_item(self, response):
  18. tr_list = response.xpath('//*[@id="morelist"]/div/table[2]//tr/td/table//tr')
  19. for tr in tr_list:
  20. title = tr.xpath('./td[2]/a[2]/@title').extract_first()
  21. status = tr.xpath('./td[3]/span/text()').extract_first()
  22. item = FbsproItem()
  23. item['title'] = title
  24. item['status'] = status
  25. print(title)
  26. yield item

settings.py

  1. # -*- coding: utf-8 -*-
  2. # Scrapy settings for fbsPro project
  3. #
  4. # For simplicity, this file contains only settings considered important or
  5. # commonly used. You can find more settings consulting the documentation:
  6. #
  7. # https://docs.scrapy.org/en/latest/topics/settings.html
  8. # https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
  9. # https://docs.scrapy.org/en/latest/topics/spider-middleware.html
  10. BOT_NAME = 'fbs_obj'
  11. SPIDER_MODULES = ['fbs_obj.spiders']
  12. NEWSPIDER_MODULE = 'fbs_obj.spiders'
  13. # Crawl responsibly by identifying yourself (and your website) on the user-agent
  14. #USER_AGENT = 'fbsPro (+http://www.yourdomain.com)'
  15. USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
  16. # Obey robots.txt rules
  17. ROBOTSTXT_OBEY = False
  18. # Configure maximum concurrent requests performed by Scrapy (default: 16)
  19. CONCURRENT_REQUESTS = 2
  20. # Configure a delay for requests for the same website (default: 0)
  21. # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
  22. # See also autothrottle settings and docs
  23. #DOWNLOAD_DELAY = 3
  24. # The download delay setting will honor only one of:
  25. #CONCURRENT_REQUESTS_PER_DOMAIN = 16
  26. #CONCURRENT_REQUESTS_PER_IP = 16
  27. # Disable cookies (enabled by default)
  28. #COOKIES_ENABLED = False
  29. # Disable Telnet Console (enabled by default)
  30. #TELNETCONSOLE_ENABLED = False
  31. # Override the default request headers:
  32. #DEFAULT_REQUEST_HEADERS = {
  33. # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  34. # 'Accept-Language': 'en',
  35. #}
  36. # Enable or disable spider middlewares
  37. # See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
  38. #SPIDER_MIDDLEWARES = {
  39. # 'fbsPro.middlewares.FbsproSpiderMiddleware': 543,
  40. #}
  41. # Enable or disable downloader middlewares
  42. # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
  43. #DOWNLOADER_MIDDLEWARES = {
  44. # 'fbsPro.middlewares.FbsproDownloaderMiddleware': 543,
  45. #}
  46. # Enable or disable extensions
  47. # See https://docs.scrapy.org/en/latest/topics/extensions.html
  48. #EXTENSIONS = {
  49. # 'scrapy.extensions.telnet.TelnetConsole': None,
  50. #}
  51. # Configure item pipelines
  52. # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  53. #ITEM_PIPELINES = {
  54. # 'fbsPro.pipelines.FbsproPipeline': 300,
  55. #}
  56. # Enable and configure the AutoThrottle extension (disabled by default)
  57. # See https://docs.scrapy.org/en/latest/topics/autothrottle.html
  58. #AUTOTHROTTLE_ENABLED = True
  59. # The initial download delay
  60. #AUTOTHROTTLE_START_DELAY = 5
  61. # The maximum download delay to be set in case of high latencies
  62. #AUTOTHROTTLE_MAX_DELAY = 60
  63. # The average number of requests Scrapy should be sending in parallel to
  64. # each remote server
  65. #AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
  66. # Enable showing throttling stats for every response received:
  67. #AUTOTHROTTLE_DEBUG = False
  68. # Enable and configure HTTP caching (disabled by default)
  69. # See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
  70. #HTTPCACHE_ENABLED = True
  71. #HTTPCACHE_EXPIRATION_SECS = 0
  72. #HTTPCACHE_DIR = 'httpcache'
  73. #HTTPCACHE_IGNORE_HTTP_CODES = []
  74. #HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
  75. #指定管道
  76. ITEM_PIPELINES = {
  77. 'scrapy_redis.pipelines.RedisPipeline': 400
  78. }
  79. #指定调度器
  80. # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
  81. DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
  82. # 使用scrapy-redis组件自己的调度器
  83. SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  84. # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
  85. SCHEDULER_PERSIST = True
  86. #指定redis
  87. REDIS_HOST = '192.168.16.119'
  88. REDIS_PORT = 6379

item.py

  1. import scrapy
  2. class FbsproItem(scrapy.Item):
  3. # define the fields for your item here like:
  4. title = scrapy.Field()
  5. status = scrapy.Field()

python爬虫--分布式爬虫的更多相关文章

  1. Python简单分布式爬虫

    分布式爬虫采用主从模式.主从模式是指由一台主机作为控制节点,负责管理所有运行网络爬虫的主机(url管理器,数据存储器,控制调度器),爬虫只需要从控制节点哪里接收任务,并把新生成任务提交给控制节点.此次 ...

  2. python的分布式爬虫框架

    scrapy + celery: Scrapy原生不支持js渲染,需要单独下载[scrapy-splash](GitHub - scrapy-plugins/scrapy-splash: Scrapy ...

  3. 初探爬虫 ——《python 3 网络爬虫开发实践》读书笔记

    零.背景 之前在 node.js 下写过一些爬虫,去做自己的私人网站和工具,但一直没有稍微深入的了解,借着此次公司的新项目,体系的学习下. 本文内容主要侧重介绍爬虫的概念.玩法.策略.不同工具的列举和 ...

  4. 爬虫--Scrapy-CrawlSpider&基于CrawlSpide的分布式爬虫

    CrawlSpider 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调par ...

  5. Python分布式爬虫原理

    转载 permike 原文 Python分布式爬虫原理 首先,我们先来看看,如果是人正常的行为,是如何获取网页内容的. (1)打开浏览器,输入URL,打开源网页 (2)选取我们想要的内容,包括标题,作 ...

  6. 基于Python,scrapy,redis的分布式爬虫实现框架

    原文  http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...

  7. 纯手工打造简单分布式爬虫(Python)

    前言 这次分享的文章是我<Python爬虫开发与项目实战>基础篇 第七章的内容,关于如何手工打造简单分布式爬虫 (如果大家对这本书感兴趣的话,可以看一下 试读样章),下面是文章的具体内容. ...

  8. python 全栈开发,Day140(RabbitMQ,基于scrapy-redis实现分布式爬虫)

    一.RabbitMQ 队列 在生产者消费模型中,比如去餐馆吃饭的例子.生产者相当于厨师,队列相当于服务员,消费者就是你. 我们必须通过服务员,才能吃饭! 如果队列满了,队列会一直hold住.必须让消费 ...

  9. 第三百七十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapyd部署scrapy项目

    第三百七十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapyd部署scrapy项目 scrapyd模块是专门用于部署scrapy项目的,可以部署和管理scrapy项目 下载地址:h ...

随机推荐

  1. 分析facebook的AsyncDisplayKit框架,async-display使用async-transaction

    上一篇<分析facebook的AsyncDisplayKit框架中的Transaction的工作原理>介绍了fb的asdk的异步事务ASAsyncTransaction,本篇介绍其在asd ...

  2. 标准库flag和cobra

    package main import "flag" var b bool var q *bool func init(){ var b bool //方式一 flag.Type( ...

  3. IDEA连接Redis

    1.创建一个Maven项目 2.在src下的pom.xml文件里,添加相关包引用 <?xml version="1.0" encoding="UTF-8" ...

  4. html——标签基础

    img标签:使用  src="xxx" 来链接图片 当图片显示不出来的时候  显示alt 中定义的内容 当图片显示了出来  鼠标移动到图片上的时候 显示的是  title 中定义的 ...

  5. Java的Arrays类 基本用法

    初识Java的Arrays类 Arrays类包括很多用于操作数组的静态方法(例如排序和搜索),且静态方法可以通过类名Arrays直接调用.用之前需要导入Arrays类: import java.uti ...

  6. Markdown学习笔记(一)

    解决Markdown文件插入图片无法只能本地查看的问题 原因:图片的显示与图片地址关联,写入Markdown时用的本机地址,一旦上传到网络,地址就发生了变化,也就显示不了图片. 寻找免费的图床网站. ...

  7. 【笔记】总结Springboot和Vue前后端分离的跨域问题

    跨域一直是个很玄学的问题,SSM的时候又得前后端一起配置,sb的时候又不用. 前端 axios普通get请求 submitForm() { var v=this; this.$axios({ meth ...

  8. NIO-概览

    目录 NIO-概览 目录 前言 什么是NIO 通道 缓冲区 选择器 其他 管道 FileLock 参考文档 NIO-概览 目录 NIO-概览 前言 本来是想学习Netty的,但是Netty是一个NIO ...

  9. 即将到来的“分布式云”(DPaaS):分布式计算+ DB +存储即服务

    我在区块链会议上就即将到来的公共"分布式云"系统进行了讨论,该系统将主流的公共云平台(如AWS,Azure,Google Cloud,Heroku等)与区块链和P2P网络相结合,比 ...

  10. window安装jboss服务器

    window安装jboss服务器 1.下载jboss服务器 地址:http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as ...