redis分布式部署

scrapy框架是否可以自己实现分布式?

不可以原因有两点

其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url。(多台机器无法共享同一个调度器)

其二:多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储。(多台机器无法共享同一个管道)

基于scrapy-redis组件的分布式爬虫

scrapy-redis组件中为我们封装好了可以被多台机器共享的调度器和管道,我们可以直接使用并实现分布式数据爬取

实现方式:

.基于该组件的RedisSpider类 ==》基于该组件的RedisCrawlSpider类

分布式实现流程:

一.修改爬虫文件
.导入scrapy-redis模块:from scrapy_redis.spiders import RedisSpider
.将当前爬虫类的父类修改成RedisSpider
.将allowed_domains和start_urls进行删除
.添加一个新的属性redis_key = 'xxx',该属性值表示的就是可以被共享的调度器队列的名称
二.进行配置文件的配置
.保证爬虫文件发起的请求都会被提交到可以被共享的调度器的队列中
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
   2.确保所有爬虫共享相同的去重指纹
     DUPEFILTER = "scrapy_redis.dupefilter.RFPDuperFilter"
.保证爬虫文件提交的item会被存储到可以被共享的管道中
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline':
}
  
   4. 在redis中保持scrapy-redis用到的队列,不会清理redis中的队列,从而实现暂停和恢复功能
  SCHEDULER_PERSTST = True
.配置最终数据存储的redis数据库
REDIS_HOST = 'redis服务的ip地址'
REDIS_PORT =
REDIS_ENCODING = ‘utf-’
REDIS_PARAMS = {‘password’:’’}
.redis数据库的配置文件进行配置:关闭保护模式和 改bind 0.0.0.0
7.开启redis服务和客户端
8.执行爬虫文件:scrapy runspider xxx.py
9.向调度器队列中仍入一个起始的url:

代码如下

1.创建项目和应用

scrapy start project redisDemo
cd redisDemo
scrapy genspider testDemo
# -*- coding: utf- -*-
import scrapy
from scrapy_redis.spiders import RedisSpider
from redisDemo.items import RedisdemoItem '''
一.修改爬虫文件
.导入scrapy-redis模块:from scrapy_redis.spiders import RedisSpider
.将当前爬虫类的父类修改成RedisSpider
.将allowed_domains和start_urls进行删除
.添加一个新的属性redis_key = 'xxx',该属性值表示的就是可以被共享的调度器队列的名称
二.进行配置文件的配置
.保证爬虫文件发起的请求都会被提交到可以被共享的调度器的队列中
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
.保证爬虫文件提交的item会被存储到可以被共享的管道中
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline':
}
.配置最终数据存储的redis数据库
REDIS_HOST = 'redis服务的ip地址'
REDIS_PORT =
REDIS_ENCODING = ‘utf-’
REDIS_PARAMS = {‘password’:’’}
.redis数据库的配置文件进行配置:关闭保护模式和 改bind 0.0.0.0
.开启redis服务和客户端
.执行爬虫文件:scrapy runspider xxx.py
.向调度器队列中仍入一个起始的url: ''' class TestdemoSpider(RedisSpider):
name = 'testDemo' # allowed_domains = ['www.x.com'] # 不注释可能会出问题
# start_urls = ['http://www.x.com/'] # 起始url需手动输入
redis_key = 'cmdb' # 表示的就是可以被共享的调度器队列的名称 url = 'http://db.pharmcube.com/database/cfda/detail/cfda_cn_instrument/%d' # 所有的url
page = # 生成所有url的公共变量 def parse(self, response):
item = RedisdemoItem() # 实例化item
item['num'] = response.xpath('/html/body/div/table/tbody/tr[1]/td[2]/text()').extract_first()
item['company_name'] = response.xpath('//html/body/div/table/tbody/tr[2]/td[2]/text()').extract_first()
item['company_address'] = response.xpath('/html/body/div/table/tbody/tr[3]/td[2]/text()').extract_first() yield item
urls = []
if self.page < :
self.page +=
new_url = format(self.url % self.page)
yield scrapy.Request(url=new_url, callback=self.parse)

testDemo.py

import scrapy

class RedisdemoItem(scrapy.Item):
# define the fields for your item here like:
num = scrapy.Field()
company_name = scrapy.Field()
company_address = scrapy.Field()

items.py

BOT_NAME = 'redisDemo'

SPIDER_MODULES = ['redisDemo.spiders']
NEWSPIDER_MODULE = 'redisDemo.spiders' # Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'redisDemo (+http://www.yourdomain.com)' # Obey robots.txt rules
ROBOTSTXT_OBEY = False
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
# 使用的是可以被共享的调度器
# 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 使用scrapy-redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
SCHEDULER_PERSIST = True # 使用scrapy-redis中封装好的可以被共享的管道
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline':
} # 配置redis
REDIS_HOST = '192.168.12.57' # ip
REDIS_PORT = # 端口
REDIS_ENCODING = 'utf-8' # 编码
# REDIS_PARAMS = {‘password’:’’} # 密码 没有就不写了

settings.py

redis配置

开启redis服务和客户端
net start redis
在爬虫应用目录下执行爬虫文件:(多台机器启动)
scrapy runspider xxx.py

需要向调度器队列中仍入一个起始的url:(不要在开启新机器了)
在redis-cli中输入 lpush cmdb http://db.pharmcube.com/database/cfda/detail/cfda_cn_instrument/1 查看内容: lrange testDemo:items 0 -1 ok,结束

增量爬取

无非判断发送请求的url或者在数据存入时候的关键字判断

# -*- coding: utf- -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from incrementDemo.items import IncrementdemoItem
from redis import Redis
import hashlib class QiubaiSpider(CrawlSpider):
name = 'qiubai'
# allowed_domains = ['www.x.com']
start_urls = ['https://www.qiushibaike.com/text/'] rules = (
Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True), # 所有页面
Rule(LinkExtractor(allow=r'/text/$'), callback='parse_item', follow=True), # 第一页面
) # 创建redis链接对象
conn = Redis(host='127.0.0.1', port=) def parse_item(self, response):
div_list = response.xpath('//div[@id="content-left"]/div') # 获取内容标签列表 for div in div_list:
item = IncrementdemoItem()
item['author'] = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first() # 作者
item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract_first() # 内容 # 将解析到的数据值生成一个唯一的标识进行redis存储
source = item['author'] + item['content']
source_id = hashlib.sha256(source.encode()).hexdigest()
# 将解析内容的唯一表示存储到redis的data_id中
ex = self.conn.sadd('data_id', source_id) if ex == :
print('该条数据没有爬取过,可以爬取......')
yield item
else:
print('该条数据已经爬取过了,不需要再次爬取了!!!')

爬虫文件

items和管道

import scrapy

class IncrementdemoItem(scrapy.Item):
# define the fields for your item here like:
author = scrapy.Field()
content = scrapy.Field()

items.py

from redis import Redis
import json class IncrementdemoPipeline(object):
conn = None def open_spider(self, spider):
self.conn = Redis(host='127.0.0.1', port=) def process_item(self, item, spider):
dic = {
'author': item['author'],
'content': item['content']
}
# print(dic)
self.conn.lpush('qiubaiData', json.dumps(dic))
return item

管道

ROBOTSTXT_OBEY = False
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36' ITEM_PIPELINES = {
'incrementDemo.pipelines.IncrementdemoPipeline': ,
}

settings.py

爬虫之scrapy-redis的更多相关文章

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

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

  2. 爬虫系列----scrapy爬取网页初始

    一 基本流程 创建工程,工程名称为(cmd):firstblood: scrapy startproject firstblood 进入工程目录中(cmd):cd :./firstblood 创建爬虫 ...

  3. Python爬虫框架Scrapy教程(1)—入门

    最近实验室的项目中有一个需求是这样的,需要爬取若干个(数目不小)网站发布的文章元数据(标题.时间.正文等).问题是这些网站都很老旧和小众,当然也不可能遵守 Microdata 这类标准.这时候所有网页 ...

  4. python爬虫之Scrapy学习

    在爬虫的路上,学习scrapy是一个必不可少的环节.也许有好多朋友此时此刻也正在接触并学习scrapy,那么很好,我们一起学习.开始接触scrapy的朋友可能会有些疑惑,毕竟是一个框架,上来不知从何学 ...

  5. 爬虫07 /scrapy图片爬取、中间件、selenium在scrapy中的应用、CrawlSpider、分布式、增量式

    爬虫07 /scrapy图片爬取.中间件.selenium在scrapy中的应用.CrawlSpider.分布式.增量式 目录 爬虫07 /scrapy图片爬取.中间件.selenium在scrapy ...

  6. 爬虫06 /scrapy框架

    爬虫06 /scrapy框架 目录 爬虫06 /scrapy框架 1. scrapy概述/安装 2. 基本使用 1. 创建工程 2. 数据分析 3. 持久化存储 3. 全栈数据的爬取 4. 五大核心组 ...

  7. python爬虫使用scrapy框架

    scrapy框架提升篇 关注公众号"轻松学编程"了解更多 1.创建启动爬虫脚本 在项目目录下创建start.py文件: 添加代码: #以后只要运行start.py就可以启动爬虫 i ...

  8. 爬虫框架-scrapy的使用

    Scrapy Scrapy是纯python实现的一个为了爬取网站数据.提取结构性数据而编写的应用框架. Scrapy使用了Twisted异步网络框架来处理网络通讯,可以加快我们的下载速度,并且包含了各 ...

  9. Python逆向爬虫之scrapy框架,非常详细

    爬虫系列目录 目录 Python逆向爬虫之scrapy框架,非常详细 一.爬虫入门 1.1 定义需求 1.2 需求分析 1.2.1 下载某个页面上所有的图片 1.2.2 分页 1.2.3 进行下载图片 ...

  10. 教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

    本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http://www.xiaohuar.com/,让你体验爬取校花的成就感. Scr ...

随机推荐

  1. MySQL8.0

    序言 my.ini [mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 basedir=D:\\DataBase\\mysql-8.0.12-winx64 # 设 ...

  2. 爬虫框架Scrapy 之(二) --- scrapy文件

    框架简介 核心部分: 引擎.下载器.调度器 自定义部分: spider(自己建的爬虫文件).管道(pipelines.py) 目录结构 firstSpider firstSpider spiders ...

  3. WebGL教程

    https://www.w3cschool.cn/webgl/rleo1oh7.html

  4. Python——将高德坐标(GCJ02)转换为GPS(WGS84)坐标

    # 官方API: http://lbs.amap.com/api/webservice/guide/api/convert # 坐标体系说明:http://lbs.amap.com/faq/top/c ...

  5. 20155324《网络对抗》Exp07 网络欺诈防范

    20155324<网络对抗>Exp07 网络欺诈防范 实践内容 简单应用SET工具建立冒名网站 ettercap DNS spoof 结合应用两种技术,用DNS spoof引导特定访问到冒 ...

  6. Android系统目录结构详解

    Android系统基于linux内核.JAVA应用,算是一个小巧精致的系统.虽是开源,但不像Linux一般庞大,娇小可亲,于是国内厂商纷纷开发出自己基于Android的操作系统.在此呼吁各大厂商眼光放 ...

  7. 通过DeviceIoControl读磁盘的方式读取独占文件内容

    前言 windows操作系统中常见的一个文件存储系统是NTFS.在这个文件系统中MFT是它的核心.             图一 MFT是一个数据结构,上图是它的结构,它主要用来存放每个文件和目录在磁 ...

  8. python复习1

    比如常用的数学常数π就是一个常量.在Python中,通常用全部大写的变量名表示常量: Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对 ...

  9. Docker-----仓库

    安装registry 安装并启动docker yum -y install docker systemctl enable docker systemctl start docker 下载regist ...

  10. spring mybatis mysql 事务不起作用

    之前框架事务应该是好的,不过这次做了些修改,不知如何竟然不好用了,整理了好半天,java框架配置就是吓人,有一点不熟悉的就可能暴露问题,好处是又深入的了解了配置原理. 开始以为是mysql不支持事务的 ...