一、说明

虽然scrapy能做的事情很多,但是要做到大规模的分布式应用则捉襟见肘。有能人改变了scrapy的队列调度,将起始的网址从start_urls里分离出来,改为从redis读取,多个客户端可以同时读取同一个redis,从而实现了分布式的爬虫。就算在同一台电脑上,也可以多进程的运行爬虫,在大规模抓取的过程中非常有效。

二、分布式爬虫原理


多了一个redis组件,主要影响两个地方:第一个是调度器。第二个是数据的处理。

Scrapy-Redis分布式策略。

作为一个分布式爬虫,是需要有一个Master端(核心服务器)的,在Master端,会搭建一个Redis数据库,用来存储start_urls、request、items。Master的职责是负责url指纹判重,Request的分配,以及数据的存储(一般在Master端会安装一个mongodb用来存储redis中的items)。出了Master之外,还有一个角色就是slaver(爬虫程序执行端),它主要负责执行爬虫程序爬取数据,并将爬取过程中新的Request提交到Master的redis数据库中。

如上图,假设我们有四台电脑:A, B, C, D ,其中任意一台电脑都可以作为 Master端 或 Slaver端。整个流程是:
首先Slaver端从Master端拿任务(Request、url)进行数据抓取,Slaver抓取数据的同时,产生新任务的Request便提交给 Master 处理;
Master端只有一个Redis数据库,负责将未处理的Request去重和任务分配,将处理后的Request加入待爬队列,并且存储爬取的数据。


Scrapy-Redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作Scrapy-Redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key就行了。

缺点是,Scrapy-Redis调度的任务是Request对象,里面信息量比较大(不仅包含url,还有callback函数、headers等信息),可能导致的结果就是会降低爬虫速度、而且会占用Redis大量的存储空间,所以如果要保证效率,那么就需要一定硬件水平。

三、案例准备

1、windows一台(从:scrapy)

2、linux一台(主:scrapy\redis\mongo)

ip:192.168.184.129

3、python3.6

linux下scrapy的配置步骤:

1、安装python3.6yum install openssl-devel -y   解决pip3不能使用的问题(pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available)下载python软件包,Python-3.6.1.tar.xz,解压后./configure --prefix=/python3makemake install  加上环境变量:PATH=/python3/bin:$PATH:$HOME/binexport PATH安装完成后,pip3默认也已经安装完成了(安装前需要先yum gcc)2、安装Twisted下载Twisted-17.9.0.tar.bz2,解压后 cd Twisted-17.9.0, python3 setup.py install3、安装scrapypip3 install scrapypip3 install scrapy-redis4、安装redis见博文redis安装与简单使用  错误:You need tcl 8.5 or newer in order to run the Redis test1、wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz2、tar -xvf tcl8.6.1-src.tar.gz3、cd tcl8.6.1/unix ; make; make installcp /root/redis-3.2.11/redis.conf /etc/启动:/root/redis-3.2.11/src/redis-server /etc/redis.conf &5、pip3 install redis6、安装mongodb启动:# mongod --bind_ip 192.168.184.129 &7、pip3 install pymongo

windows上scrapy的部署步骤:

1、安装wheelpip install wheel2、安装lxmlhttps://pypi.python.org/pypi/lxml/4.1.03、安装pyopensslhttps://pypi.python.org/pypi/pyOpenSSL/17.5.04、安装Twistedhttps://www.lfd.uci.edu/~gohlke/pythonlibs/5、安装pywin32https://sourceforge.net/projects/pywin32/files/6、安装scrapypip install scrapy

四、案例部署代码

以某某天堂的电影爬取为简单例子,说一下分布式的实现,代码linux和windows上各放一份,配置一样,两者可同时运行爬取。

只列出需要修改的地方:

settings

设置爬取数据的存储数据库(mongodb),指纹和queue存储的数据库(redis)

ROBOTSTXT_OBEY = False  # 禁止robot
CONCURRENT_REQUESTS = 1  # scrapy调试queue的最大并发,默认16
ITEM_PIPELINES = {'meiju.pipelines.MongoPipeline': 300,
}
MONGO_URI = '192.168.184.129'  # mongodb连接信息
MONGO_DATABASE = 'mj'
SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 使用scrapy_redis的调度
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"  # 在redis库中去重(url)
# REDIS_URL = 'redis://root:kongzhagen@localhost:6379'  # 如果redis有密码,使用这个配置
REDIS_HOST = '192.168.184.129'  #redisdb连接信息
REDIS_PORT = 6379
SCHEDULER_PERSIST = True  # 不清空指纹

piplines

存储到MongoDB的代码

import pymongoclass MeijuPipeline(object):def process_item(self, item, spider):return itemclass MongoPipeline(object):collection_name = 'movies'def __init__(self, mongo_uri, mongo_db):self.mongo_uri = mongo_uriself.mongo_db = mongo_db@classmethoddef from_crawler(cls, crawler):return cls(mongo_uri=crawler.settings.get('MONGO_URI'),mongo_db=crawler.settings.get('MONGO_DATABASE', 'items'))def open_spider(self, spider):self.client = pymongo.MongoClient(self.mongo_uri)self.db = self.client[self.mongo_db]def close_spider(self, spider):self.client.close()def process_item(self, item, spider):self.db[self.collection_name].insert_one(dict(item))return item

items

数据结构

import scrapyclass MeijuItem(scrapy.Item):movieName = scrapy.Field()status = scrapy.Field()english = scrapy.Field()alias = scrapy.Field()tv = scrapy.Field()year = scrapy.Field()type = scrapy.Field()

scrapy脚本mj.py

# -*- coding: utf-8 -*-
import scrapy
from scrapy import Requestclass MjSpider(scrapy.Spider):name = 'mj'allowed_domains = ['meijutt1.com']# start_urls = ['http://www.example1.com/file/list1.html']def start_requests(self):yield Request(url='http://www.example1.com/file/list1.html', callback=self.parse)def parse(self, response):from meiju.items import MeijuItemmovies = response.xpath('//div[@class="cn_box2"]')for movie in movies:item = MeijuItem()item['movieName'] = movie.xpath('./ul[@class="list_20"]/li[1]/a/text()').extract_first()item['status'] = movie.xpath('./ul[@class="list_20"]/li[2]/span/font/text()').extract_first()item['english'] = movie.xpath('./ul[@class="list_20"]/li[3]/font[2]/text()').extract_first()item['alias'] = movie.xpath('./ul[@class="list_20"]/li[4]/font[2]/text()').extract_first()item['tv'] = movie.xpath('./ul[@class="list_20"]/li[5]/font[2]/text()').extract_first()item['year'] = movie.xpath('./ul[@class="list_20"]/li[6]/font[2]/text()').extract_first()item['type'] = movie.xpath('./ul[@class="list_20"]/li[7]/font[2]/text()').extract_first()yield itemfor i in response.xpath('//div[@class="cn_box2"]/ul[@class="list_20"]/li[1]/a/@href').extract():yield Request(url='http://www.example1.com' + i)# next = 'http://www.example1.com' + response.xpath("//a[contains(.,'下一页')]/@href")[1].extract()# print(next)# yield Request(url=next, callback=self.parse)

在这里插入图片描述

看一下redis中的情况:

看看mongodb中的数据:

Python-玩转数据-scrapy简单分布式爬虫相关推荐

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

    https://www.cnblogs.com/qiyeboy/p/7016540.html 本章讲的依旧是实战项目,实战内容是打造分布式爬虫,这对初学者来说,是一个不小的挑战,也是一次有意义的尝试. ...

  2. python好学吗mooc中文网-用Python玩转数据

    spContent=欢迎来到<用Python玩转数据>,这是第10次开课,大壮老师会尽量用非计算机专业(需要有一些编程基础,最好学过一门程序设计语言,但不一定是Python)小伙伴们能听懂 ...

  3. 新农慕课python项目答案_2020中国大学慕课用Python玩转数据答案搜题公众号

    2020中国大学慕课用Python玩转数据答案搜题公众号 更多相关问题 低碳钥Q235钢板对接时,焊条应选用().A.E7015B.E6015C.E5515D.E4303 不属于无线宽带接入技术的() ...

  4. 慕课《用Python玩转数据》之B站弹幕数据分析

    慕课<用Python玩转数据>之B站弹幕数据分析 1.源代码 # -*- coding: utf-8 -*- """ Created on Wed May 1 ...

  5. 大学python选择题题库及答案_大学慕课用Python玩转数据题库及答案

    大学慕课用Python玩转数据题库及答案 更多相关问题 (19分)电解原理在化学工业中有广泛应用.右图表示一个电解池,装有电解液c :A.B是两块电极板,通过导线与直流 用铂电极电解CuCl2与CuS ...

  6. python好学吗mooc中文网-2020年大学mooc用Python玩转数据作业答案

    2020年大学mooc用Python玩转数据作业答案 更多相关问题 一台电脑先涨价着一%,后降价2一%,这台电脑一现价同原价相比是()A.一样的B.降低了C.提高了直接写出9数 3÷地下%=6×3下% ...

  7. pythonzerojudge题库及答案_大学mooc2020用Python玩转数据试题及答案

    大学mooc2020用Python玩转数据试题及答案 更多相关问题 胆汁酸生成的限速酶是: [单选题]以下哪个是结核治疗策略: [单选题]胆汁酸生成的限速酶是: [判断题]仰光大金塔塔体是在3层大台基 ...

  8. 确实会玩!教你用Python玩转数据~

    向大家推荐一个南京大学的公开课--用Python玩转数据 授课老师张莉博士是南京大学计算机科学与技术系副教授,主要研究领域为数据挖掘和自然语言处理.张老师上课走亲切风冷幽默路线,跟同学们相处愉快,常常 ...

  9. PDF课件下载!《用Python玩转数据》

    向大家推荐一个南京大学的公开课--用Python玩转数据 授课老师张莉博士是南京大学计算机科学与技术系副教授,主要研究领域为数据挖掘和自然语言处理.张老师上课走亲切风冷幽默路线,跟同学们相处愉快,常常 ...

最新文章

  1. MySQL中字段约束有哪些_mysql字段约束
  2. sql语句中having的作用是?
  3. AMP328音频放大器
  4. 第二章:2.8 通过Django 在web页面上面输出 “Hello word ”
  5. go语言socket通信初试
  6. 平台游戏中走与跳的实现
  7. hihoCoder1353 满减优惠
  8. Windows10 手机应用程序开发 - 3. 做一个简单的计算器界面
  9. Spark学习之Spark Streaming
  10. echarts 柱状图 ,颜色和显示设置
  11. java2实用教程知识点_Java2实用教程(第5版)重要点及遗漏点(三)
  12. 命令:服务器与CST时间误差8小时的修复方法——timedatectl
  13. 如何简单粗暴地上手 TensorFlow 2.0?
  14. MFC中Socket网络通讯
  15. 一款好看的 VSCode 代码主题和图标主题
  16. 2022重庆大学877软件工程考研经验贴
  17. 启科量子开源量子编程框架 QuTrunk
  18. FWT快速沃尔什变换及其应用
  19. 接入高德地图第三方SDK——如何获取API Key
  20. Just For Fun(乐者为王)——Linux创始人

热门文章

  1. 2017年第4届中国西部门窗博览会会刊(参展商名录)
  2. Linux下的超级终端(minicom)
  3. 谷歌浏览器:embed引入PDF出现缩略图、工具栏
  4. python最大团问题
  5. 英特尔网卡更新firmware方法
  6. 图片大小与什么有关?图片大小怎么改小?
  7. 开始自学SAP以及学习路线
  8. 超音速启动 2020 年版发布
  9. Spring------基于xml的DI (一)设值注入、构造注入
  10. Arduino粉尘烟雾传感器PM2.5实验