scrapy-redis分布式

来自scrapy-redis包的知识

前言

scrapy-redis是一个python包, 是scrapy基于redis的一个组件. 用于scrapy爬虫分布式开发.

在环境配置OK下, 将原有的scrapy项目copy到其他主机上运行就行.

使用该工具需要环境: python3, redis, scrapy.


安装

window: pip install scrapy-redis

ubuntu: pip3 install scrapy-redis


使用

大致过程: 在多台主机环境下, spider开始运行在各主机上, spider请求的request和item会发送到redis中的队列中进行排列和去重, 同时各主机的spider也会从master(即redis所在主机)的redis中取下一步需要请求的request, 就这样循环下去.

要使用scrapy-redis很简单, 将spider类继承RedisSpider类, 再设置redis_key(类似start_urls)和settings文件.

spider设置

# 下面是爬longzhu_app数据的spider代码, 改变一下.
# -*- coding: utf-8 -*-
import scrapy
from longzhu.items import LongzhuItem
import json
from urllib.request import urlretrieve
from scrapy_redis.spider import RedisSpider		# 导入.

# 我们在这继承RedisSpier类.
class BeautySpider(RedisSpider):
	name = 'beauty'
	allowed_domains = ['longzhu.com']
	#start_urls = ['需要请求的json_url'], 没做post处理, url太长不放出来了.
	redis_key = 'longzhu:start_urls'	# 最好是这样的命名方式, project:start_urls
	basic_url = "http://y.longzhu.com/"
	image_path = "图片存放的文件夹"
	offset = 0

	def parse(self, response):
		datas = json.loads(response.text)['data']['streamFlows'][0]['streams']
		for data in datas:
			item = LongzhuItem()
			item['room_id'] = data['room']['domain']
			item['room_title'] = data['room']['title']
			item['room_href'] = self.basic_url + item['room_id']
			item['room_one'] = data['user']['name']
			item['online_amount'] = data['room']['viewers']
			item['follow_amount'] = data['user']['fans_num']
			item['one_picture'] = data['cover']
			if urlretrieve(item['one_picture'], self.image_path + item['room_one']) is not None:
				self.offset += 1
				print(f"{self.offset} picture is download.")
			yield item

settings

# 我们需要将下面的几条配置加入到settings中.
# 1.使用了scrapy_redis的去重组件,在redis数据库里做去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 2.使用了scrapy_redis的调度器,在redis里分配请求
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 3.在redis中保持scrapy-redis用到的各个队列,从而True允许暂停和暂停后恢复,也就是不清理redis_queues
# False就是清理. 一般我们设置为True.
SCHEDULER_PERSIST = True

# 4.通过配置RedisPipeline将item写入key为 spider.name : items 的redis的list中,供后面的分布式处理
# item这个已经由 scrapy-redis 实现,不需要我们写代码,直接使用即可
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 100
}

# 5.指定redis数据库的连接参数, 信息为主机的ip和port.
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379

在这些设置好了以后, 就可以scrapy runspider spiderfile运行了, 运行后scrapy会进入阻塞状态, 我们这里进去redis中, 使用lpush longzhu:start_urls '第一个需要请求的URL'(和spider中的redis_key一样.), 将url扔到redis中, 阻塞状态中的scrapy查询到了就会取这个url开始请求并开始运行, 运行结果会保存在redis中等待开发者做进一步处理.

result

# 在redis中会出现如下 4 个对象.

"项目名:items" 
list类型,保存爬虫获取到的数据item, 内容是json字符串.
	
"项目名:dupefilter"
set类型, 用于爬虫访问的URL去重, 内容是40个字符的 url 的hash字符串.

"项目名: start_urls"
List类型, 用于获取spider启动时爬取的第一个url.

"项目名:requests"
zset类型, 用于scheduler调度处理requests内容是request对象的序列化字符串.

猜你喜欢

转载自blog.csdn.net/One_of_them/article/details/81633878