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. Aras SP9里打开自己写的网页。

    首先把自己写的网页挂在IIS里或者网站挂到IIS里面. 然后再Aras里新增method //网页参数 var dialogArguments = new Array(); //窗体参数 var op ...

  2. sql server 查询log日志 sql语句

    xp_readerrorlog 一共有7个参数: 1. 存档编号 2. 日志类型(1为SQL Server日志,2为SQL Agent日志) 3. 查询包含的字符串 4. 查询包含的字符串 5. Lo ...

  3. JS判断页面是在浏览器还是微信打开

    一.Navigator对象 1.获取用户的浏览器信息. let ua = navigator.userAgent.toLowerCase(); 打印一下ua的结果: Mozilla/5.0 (Maci ...

  4. day 21 - 1 包,异常处理

    创建目录代码 1. 无论是 import 形式还是 from...import 形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法2. 包是目录级的(文 ...

  5. mysql 5.7~默认sql_mode解读

    当5.6升级到5.7时,首先要注意的就是sql_mode对业务的影响 大概可以分为几类1 共同支持,如果你的5.6和5.7sql_mode配置支持的交集一样,那么不用考虑2 5.7细说  1 ONLY ...

  6. 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165237

    2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 20165237 安装虚拟机 首先创建虚拟机 创建好虚拟机后,打开虚拟机进行安装.第一步选择Graphcal i ...

  7. 2018-2019-2 20165234 《网络对抗技术》 Exp4 恶意代码分析

    实验四 恶意代码分析 实验目的 1.监控自己系统的运行状态,看有没有可疑的程序在运行. 2.分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals ...

  8. Access denied for user ‘root’@‘localhost’(using password: YES)的解决方法

    https://www.jb51.net/article/133836.htm 搭建服务器之后只能看见test与infomation_schema两个库 https://www.cnblogs.com ...

  9. request模块

    一 介绍 二 基于GET请求 三 基于POST请求 四 响应Response 五 高级用法 一 介绍 # 介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模 ...

  10. kibana转码显示

    $('.truncate-by-height').each((i, dom) => { $(dom).html(decodeURIComponent($(dom).html())) })