2025年3月29日 星期六 甲辰(龙)年 月廿八 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

爬虫--Scrapy-redis分布式爬虫(基础)

时间:08-16来源:作者:点击数:21
CDSY,CDSY.XYZ

安装scrapy-redis

  • pip install scrapy-redis -i https://pypi.douban.com/simple

Scrapy-Redis分布式策略

  • 假设有四台电脑:Windows 10、Mac OS X、Ubuntu 16.04、CentOS 7.2,任意一台电脑都可以作
  • 为 Master端 或 Slaver端,比如:
  • - `Master端`(核心服务器) :使用 Windows 10,搭建一个Redis数据库,不负责爬取,只负责url指
  • - 纹判重、Request的分配,以及数据的存储
  • - `Slaver端`(爬虫程序执行端) :使用 Mac OS X 、Ubuntu 16.04、CentOS 7.2,负责执行爬虫程
  • - 序,运行过程中提交新的Request给Master
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jw33HV2u-16024
  • 25589171)(img/masterAndslaver.png)]
  • 1. 首先Slaver端从Master端拿任务(Request、url)进行数据抓取,Slaver抓取数据的同时,产
  • 2. 生新任务的Request便提交给 Master 处理;
  • 3. Master端只有一个Redis数据库,负责将未处理的Request去重和任务分配,将处理后的Requ
  • 4. est加入待爬队列,并且存储爬取的数据。
  • Scrapy-Redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作Scrapy-
  • Redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key就行了。
  • 缺点是,Scrapy-Redis调度的任务是Request对象,里面信息量比较大(不仅包含url,还有ca
  • llback函数、headers等信息),可能导致的结果就是会降低爬虫速度、而且会占用Redis大量
  • 的存储空间,所以如果要保证效率,那么就需要一定硬件水平。

安装Redis

  • 准备两台电脑 都装redis
  • master端
  • 可以保证master上面的redis可以被连接
  • 注意:redis默认配置是不让远程连接,需要注释掉redis.conf配置文件中
  • 的 #bind 127.0.0.1 #protected-mode no
  • 启动master端的redis数据库
  • redis--cli --启动本地数据库
  • ping --检测数据库连接状态,返回PONG,则表示成功
  • set key1 'hello' -- 存入{'key1':'hello'}
  • slave端
  • redis-cli -h 192.168.199.108-h 参数表示连接到指定主机的redis数据库地址 -p 可以指定端口
  • --keys 查询刚才存入的键数据
  • -- get key1 查询刚才存入的key1的值
  • 如果查询到刚才在master端存入的数据则表示配置成功
  • 注意:Slave端无需启动redis-server,Master端启动即可。只要 Slave 端读取到了 Master 端的
  • Redis 数据库,则表示能够连接成功,可以实施分布式。

分布式爬虫源码

  • 链接:https://pan.baidu.com/s/16aXPHtePiarEIFATwcILbw 提取码:hhhh

源码详解

一、dmoz (class DmozSpider(CrawlSpider))

这个爬虫继承的是CrawlSpider,它是用来说明Redis的持续性,当我们第一次运行dmoz爬

虫,然后Ctrl + C停掉之后,再运行dmoz爬虫,之前的爬取记录是保留在Redis里的。

分析起来,其实这就是一个 scrapy-redis 版 CrawlSpider 类,需要设置Rule规则,以及callback

不能写parse()方法。

执行方式:scrapy crawl dmoz

  • from scrapy.linkextractors import LinkExtractor
  • from scrapy.spiders import CrawlSpider, Rule
  • class DmozSpider(CrawlSpider):
  • """Follow categories and extract links."""
  • name = 'dmoz'
  • allowed_domains = ['dmoztools.net/']
  • start_urls = ['http://dmoztools.net/']
  • rules = [
  • Rule(LinkExtractor(
  • restrict_css=('.top-cat', '.sub-cat', '.cat-item')
  • ), callback='parse_directory', follow=True),
  • ]
  • def parse_directory(self, response):
  • for div in response.css('.title-and-desc'):
  • yield {
  • 'name': div.css('.site-title::text').extract_first(),
  • 'description': div.css('.site-descr::text').extract_first().strip(),
  • 'link': div.css('a::attr(href)').extract_first(),
  • }

二、mycrawler_redis (class MyCrawler(RedisCrawlSpider))

这个RedisCrawlSpider类爬虫继承了RedisCrawlSpider,能够支持分布式的抓取。因为采

用的是crawlSpider,所以需要遵守Rule规则,以及callback不能写parse()方法。

同样也不再有start_urls了,取而代之的是redis_key,scrapy-redis将key从Redis里pop出

来,成为请求的url地址。

  • from scrapy.spiders import Rule
  • from scrapy.linkextractors import LinkExtractor
  • from scrapy_redis.spiders import RedisCrawlSpider
  • class MyCrawler(RedisCrawlSpider):
  • """Spider that reads urls from redis queue (myspider:start_urls)."""
  • # 爬虫名
  • name = 'mycrawler_redis'
  • # redis_key: 类似start_url,但是只是redis的一个key
  • # 监听redis中的key
  • redis_key = 'mycrawler:start_urls'
  • # 允许的域名
  • allowed_domains = ['dmoz.org']
  • # 规则
  • rules = (
  • Rule(LinkExtractor(), callback='parse_page', follow=True),
  • )
  • # __init__方法必须按规定写,使用时只需要修改super()里的类名参数即可
  • def __init__(self, *args, **kwargs):
  • # Dynamically define the allowed domains list.
  • domain = kwargs.pop('domain', '')
  • self.allowed_domains = filter(None, domain.split(','))
  • # 修改这里的类名为当前类名
  • super(MyCrawler, self).__init__(*args, **kwargs)
  • def parse_page(self, response):
  • return {
  • 'name': response.css('title::text').extract_first(),
  • 'url': response.url,
  • }
  • 注意:
  • 同样的,RedisCrawlSpider类不需要写allowd_domains和start_urls:
  • scrapy-redis将从在构造方法__init__()里动态定义爬虫爬取域范围,也可以选择直接写allowd_domains。
  • 必须指定redis_key,即启动爬虫的命令,参考格式:redis_key = 'myspider:start_urls'
  • 根据指定的格式,start_urls将在 Master端的 redis-cli 里 lpush 到 Redis数据库里,RedisSpider 将在数据
  • 库里获取start_urls。
  • 执行方式:
  • 通过runspider方法执行爬虫的py文件(也可以分次执行多条),爬虫(们)将处于等待准备状态:
  • scrapy runspider mycrawler_redis.py
  • 在Master端的redis-cli输入push指令,参考格式:
  • $redis > lpush mycrawler:start_urls http://www.dmoz.org/
  • 爬虫获取url,开始执行。

三、myspider_redis (class MySpider(RedisSpider))

这个爬虫继承了RedisSpider, 它能够支持分布式的抓取,采用的是basic spider,需要

写parse函数。

其次就是不再有start_urls了,取而代之的是redis_key,scrapy-redis将key从Redis里po

p出来,成为请求的url地址。

  • from scrapy_redis.spiders import RedisSpider
  • class MySpider(RedisSpider):
  • """Spider that reads urls from redis queue (myspider:start_urls)."""
  • # 爬虫名
  • name = 'myspider_redis'
  • # redis_key: 类似start_url,但是只是redis的一个key
  • # 监听当前爬虫所连接的redis数据库中的指定key为‘myspider:start_urls’是否改变
  • redis_key = 'myspider:start_urls'
  • # 允许的域名
  • allowed_domains = ['dmoz.org']
  • def parse(self, response):
  • pass
  • 注意:
  • RedisSpider类 不需要写allowd_domains和start_urls:
  • scrapy-redis将从在构造方法__init__()里动态定义爬虫爬取域范围,也可以选择直接
  • 写allowd_domains。
  • 必须指定redis_key,即启动爬虫的命令,参考格式:redis_key = 'myspider:start_urls'
  • 根据指定的格式,start_urls将在 Master端的 redis-cli 里 lpush 到 Redis数据库里,RedisS
  • pider 将在数据库里获取start_urls。
  • 执行方式:
  • 通过runspider方法执行爬虫的py文件(也可以分次执行多条),爬虫(们)将处于等待准备状态:
  • scrapy runspider myspider_redis.py
  • 在Master端的redis-cli输入push指令,参考格式:
  • $redis > lpush myspider:start_urls http://dmoztools.net/
  • Slaver端爬虫获取到请求,开始爬取。

总结:

如果只是用到Redis的去重和保存功能,就选第一种;

如果要写分布式,则根据情况,选择第二种、第三种;

通常情况下,会选择用第二种方式编写深度聚焦爬虫

CDSY,CDSY.XYZ
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐