原理:其实就是用到redis的优点及特性,好处自己查---

1,scrapy 分布式爬虫配置:

settings.py

BOT_NAME = 'first'

SPIDER_MODULES = ['first.spiders']
NEWSPIDER_MODULE = 'first.spiders' # Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'first (+http://www.yourdomain.com)' # Obey robots.txt rules
ROBOTSTXT_OBEY = False # Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16 # Disable cookies (enabled by default)
#COOKIES_ENABLED = False ITEM_PIPELINES = {
# 'first.pipelines.FirstPipeline': 300,
'scrapy_redis.pipelines.RedisPipeline':300,
'first.pipelines.VideoPipeline': 100,
} #分布式爬虫
#指定redis数据库的连接参数
REDIS_HOST = '172.17.0.2'
REDIS_PORT = 15672
REDIS_ENCODING = 'utf-8'
# REDIS_PARAMS ={
# 'password': '123456', # 服务器的redis对应密码
# }
#使用了scrapy_redis的调度器,在redis里分配请求
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# # 确保所有爬虫共享相同的去重指纹
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# Requests的调度策略,默认优先级队列
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
#(可选). 在redis中保持scrapy-redis用到的各个队列,从而允许暂停和暂停后恢复,也就是不清理redis queues
SCHEDULER_PERSIST = True

spider.py

# -*- coding: utf-8 -*-
import scrapy
import redis
from ..items import Video
from scrapy.http import Request
from scrapy_redis.spiders import RedisSpider
class VideoRedis(RedisSpider):
name = 'video_redis'
allowed_domains = ['zuidazy2.net']
# start_urls = ['http://zuidazy2.net/']
redis_key = 'zuidazy2:start_urls'
def parse(self, response):
item = Video()
res= response.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb4"]/a/text()').extract_first()
url = response.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb4"]/a/@href').extract_first()
v_type = response.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb5"]/text()').extract_first()
u_time = response.xpath('//div[@class="xing_vb"]/ul/li/span[@class="xing_vb6"]/text()').extract_first()
if res is not None:
item['name'] = res
item['v_type'] = v_type
item['u_time'] = u_time
url = 'http://www.zuidazy2.net' + url
yield scrapy.Request(url, callback=self.info_data,meta={'item': item},dont_filter=True)
next_link = response.xpath('//div[@class="xing_vb"]/ul/li/div[@class="pages"]/a[last()-1]/@href').extract_first()
if next_link:
yield scrapy.Request('http://www.zuidazy2.net'+next_link,callback=self.parse,dont_filter=True) def info_data(self,data):
item = data.meta['item']
res = data.xpath('//div[@id="play_2"]/ul/li/text()').extract()
if res:
item['url'] = res
else:
item['url'] = ''
yield item

items.py

import scrapy

class FirstItem(scrapy.Item):
# define the fields for your item here like:
content = scrapy.Field() class Video(scrapy.Item):
name = scrapy.Field()
url = scrapy.Field()
v_type = scrapy.Field()
u_time = scrapy.Field()

pipelines.py

from pymysql import *
import aiomysql
class FirstPipeline(object):
def process_item(self, item, spider):
print('*'*30,item['content'])
return item class VideoPipeline(object):
def __init__(self):
self.conn = connect(host="39.99.37.85",port=3306,user="root",password="",database="queyou")
self.cur = self.conn.cursor() def process_item(self, item, spider): # print(item)
try:
# insert_sql = f"insert into video values(0,'{item['name']}','{item['url']}','{item['v_type']}','{item['u_time']}')"
# self.cur.execute(insert_sql)
# # self.cur.execute("insert into video values(0,'"+item['name']+"','"+item['url']+"','"+item['v_type']+"','"+item['u_time']+"')")
self.cur.execute("insert into video values(0,'"+item['name']+"','"+item['v_type']+"')")
self.conn.commit()
except Exception as e:
print(e)
finally:
return item
def close_spider(self, spider):
self.conn.commit() # 提交数据
self.cur.close()
self.conn.close()

2,Docker 安装和pull centos7 及安装依赖  (跳过)

3,cp 宿主机项目到 Centos7 容器中

docker cp /root/first 35fa:/root

4,安装redis 及 开启远程连接服务

具体在 /etc/redis.conf 中设置和开启redis服务

redis-server /etc/redis.conf

5,Docker虚拟主机多个及建立通信容器

运行容器
docker run -tid --name 11 CONTAINER_ID 建立通信容器
docker run -tid --name 22 --link 11 CONTAINER_ID 进入容器 docker attach CONTAINER_ID 退出容器,不kill掉容器(通常exit会kill掉的) ctrl+q+p
查看网络情况 cat /etc/hosts

5,开启所有容器的spider 及定义start_url

完工!

附上打包好的镜像:链接: https://pan.baidu.com/s/1Sj244da0pOZvL3SZ_qagUg 提取码: qp23

Centos7__Scrapy + Scrapy_redis 用Docker 实现分布式爬虫的更多相关文章

  1. 分布式爬虫scrapy-redis

    第一步 下载scrapy模块: pip install scrapy-redis 第二步 创建项目 在终端/cmd进入创建项目的目录: cd 路径: scrapy startproject douba ...

  2. scrapy分布式爬虫scrapy_redis二篇

    =============================================================== Scrapy-Redis分布式爬虫框架 ================ ...

  3. scrapy分布式爬虫scrapy_redis一篇

    分布式爬虫原理 首先我们来看一下scrapy的单机架构:     可以看到,scrapy单机模式,通过一个scrapy引擎通过一个调度器,将Requests队列中的request请求发给下载器,进行页 ...

  4. 使用Docker Swarm搭建分布式爬虫集群

    https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653195618&idx=2&sn=b7e992da6bd1b2 ...

  5. scrapy_redis分布式爬虫

    文章来源:https://github.com/rmax/scrapy-redis Scrapy-Redis Documentation: https://scrapy-redis.readthedo ...

  6. python3下scrapy爬虫(第十三卷:scrapy+scrapy_redis+scrapyd打造分布式爬虫之配置)

    之前我们的爬虫都是单机爬取,也是单机维护REQUEST队列, 看一下单机的流程图: 一台主机控制一个队列,现在我要把它放在多机执行,会产生一个事情就是做重复的爬取,毫无意义,所以分布式爬虫的第一个难点 ...

  7. 利用scrapy_redis实现分布式爬虫

    介绍 Scrapy框架不支持分布式,所以需要将一些关键代码进行修改使之支持分布式.scrapy-redis相当于一个插件,用来替换scrapy中的一些模块,使得scrapy支持分布式.github地址 ...

  8. python3 分布式爬虫

    背景 部门(东方IC.图虫)业务驱动,需要搜集大量图片资源,做数据分析,以及正版图片维权.前期主要用node做爬虫(业务比较简单,对node比较熟悉).随着业务需求的变化,大规模爬虫遇到各种问题.py ...

  9. scrapy-redis 分布式爬虫

    为什么要学? Scrapy_redis在scrapy的基础上实现了更多,更强大的功能. 有哪些功能体现? request去重.爬虫持久化.实现分布式爬虫.断点续爬(带爬取的request存在redis ...

随机推荐

  1. 实用简易的U盘修复工具推荐

    如果我们的U盘出现可以读取,但不能打开,或是提示格式化的情况,那可能是U盘硬件出现了问题.U盘内部部件损坏就只能维修了,如果是u盘出现逻辑错误,常用的解决方法就是到网上下载一个u盘修复工具,对u盘进行 ...

  2. 聊聊 elasticsearch 之分词器配置 (IK+pinyin)

    系统:windows 10 elasticsearch版本:5.6.9 es分词的选择 使用es是考虑服务的性能调优,通过读写分离的方式降低频繁访问数据库的压力,至于分词的选择考虑主要是根据目前比较流 ...

  3. php数字运算与格式化

    浮点数高精度运算 PHP 官方手册 浮点数的精度有限.尽管取决于系统,PHP 通常使用 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16.非基本数学运算可能会给出更大误 ...

  4. rest-framework 解析器

    一 解析器的作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等格 ...

  5. 面经手册 · 第20篇《Thread 线程,状态转换、方法使用、原理分析》

    作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...

  6. 饱含辛酸开发 WPF CustomControl

    引言 不知不觉间WPF开发已有两年光景,或许有很多人会问WPF还需要学习吗?WPF还有前途吗?其实我也很担心这个问题. .Net Core3.x已经支持WPF开发,.Net 5也宣布要支持WPF.是否 ...

  7. PyQt学习随笔:自定义信号连接时报AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 如果使用自定义信号,一定要记得信号是类变量,必须在类中定义,不能在实例 ...

  8. PyQt(Python+Qt)学习随笔:QToolBox工具箱currentItem对应的index、text、name、icon、ToolTip属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在Designer中,toolBox主要有如下属性: 可以看到,toolBox的属性主要是与当前项相 ...

  9. 转:Python常见字符编码及其之间的转换

    参考:Python常见字符编码 + Python常见字符编码间的转换 一.Python常见字符编码 字符编码的常用种类介绍 第一种:ASCII码 ASCII(American Standard Cod ...

  10. PyQt(Python+Qt)学习随笔:QTableWidget的获取指定位置项的item和itemAt方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 1.获取指定行和列的项 根据行和列可以获取对应位置的项,调用语法如下: QTableWidgetIt ...