scrapy(六)scrapy

mac2024-10-19  49

scrapy 是一个通用的爬虫框架 分布式爬虫 共享队列 所有请求位于队列之中 如何实现队列共享? 队列位于内存中,redis是一种内存数据库 不同电脑可访问redis这个内存数据库 管道是数据的存储 基于scrapy实现分布式扩展的组件scrapy_redis scrapy_redis重写了scrapy组件

scrapy-redis的使用

1.1、介绍

scrapy_redis是一个基于Redis的Scrapy组件,用于scrapy项目的分布式部署和开发。

特点:

分布式爬取 你可以启动多个spider对象,互相之间共享有一个redis的request队列。最适合多个域名的广泛内容的爬取。

分布式数据处理 爬取到的item数据被推送到redis中,这意味着你可以启动尽可能多的item处理程序。

scrapy即插即用

scrapy调度程序+过滤器,项目管道,base spidre,使用简单。

1.2、安装

pip install scrapy-redis -i https://pypi.doubanio.com/simple 可直接下载scrapy-redis文件

若出现报错 请点击下方链接 redis

1.3、设置

默认redis的地址和端口

REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379

启用调度将请求存储进redis,建立和redis的链接

SCHEDULER = "scrapy_redis.scheduler.Scheduler"

确保所有spider通过redis共享相同的重复过滤。

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

不清理redis队列(持久化队列),允许暂停/恢复抓取。

SCHEDULER_PERSIST = True

1.4、运行

队列存入到redis内存数据库中,并未被释放 原因是settings中代码,作用是持久化 注释后就从start_url开始 Linux(虚拟机)下操作redis删除记录

redis-cli keys * del dmoz:dupefilter del dmoz:requests del name

删除redis记录后,队列被删除,运行代码,请求重新从start_url开始

复习:pycharm如何连接虚拟机中的Linux运行scrapy

1 在Linux中mkdir一个文件夹 2 创建pycharm与虚拟机的链接 3、将文件上传至linux 5 最好退出虚拟环境

2、组件

scrapy_redis项目流程

首先创建scrapy项目修改settings中默认的调度器和过滤在spider里修改继承的类RedisSpider使用 redis_key, 需要在redis数据库中键盘添加start_urls

2.1、myspider_redis文件

继承的RedisSpider类 能从键盘输入start_urls

127.0.0.1:6379> LPUSH myspider:start_urls https://www.baidu.com (integer) 1 127.0.0.1:6379>

LPUSH的不会去重

自动生成一个items保存到redis,这样保存在内存中(去重)很耗费内存

127.0.0.1:6379> type myspider_redis:items list 127.0.0.1:6379> lrange myspider_redis:items 0 10 1) "{\"name\": \"\\u767e\\u5ea6\\u4e00\\u4e0b\\uff0c\\u4f60\\u5c31\\u77e5\\u9053\", \"url\": \"https://www.baidu.com\", \"crawled\": \"2019-11-02 07:09:53 \", \"spider\": \"myspider_redis\"}" 2) "{\"name\": \"\\u767e\\u5ea6\\u4e00\\u4e0b\\uff0c\\u4f60\\u5c31\\u77e5\\u9053\", \"url\": \"https://www.baidu.com\", \"crawled\": \"2019-11-02 07:27:23 \", \"spider\": \"myspider_redis\"}" 3) "{\"name\": \"\\u767e\\u5ea6\\u4e00\\u4e0b\\uff0c\\u4f60\\u5c31\\u77e5\\u9053\", \"url\": \"https://www.baidu.com\", \"crawled\": \"2019-11-02 07:28:07 \", \"spider\": \"myspider_redis\"}" 4) "{\"name\": \"\\u4eac\\u4e1c(JD.COM)-\\u6b63\\u54c1\\u4f4e\\u4ef7\\u3001\\u54c1\\u8d28\\u4fdd\\u969c\\u3001\\u914d\\u9001\\u53ca\\u65f6\\u3001\\u8f7b\\ u677e\\u8d2d\\u7269\\uff01\", \"url\": \"https://www.jd.com\", \"crawled\": \"2019-11-02 07:34:32\", \"spider\": \"myspider_redis\"}" 127.0.0.1:6379>

这样保存在内存中(去重)很耗费内存,所以常用MongoDB和mysql保存网址(去重)

2.2、调度器

pipelines

存储数据到redis

2.3、去重原理

def next_requests(self): """Returns a request to be scheduled or none.""" use_set = self.settings.getbool('REDIS_START_URLS_AS_SET', defaults.START_URLS_AS_SET) fetch_one = self.server.spop if use_set else self.server.lpop # XXX: Do we need to use a timeout here? found = 0 # TODO: Use redis pipeline execution. while found < self.redis_batch_size: data = fetch_one(self.redis_key) if not data: # Queue empty. break req = self.make_request_from_data(data) if req: yield req found += 1 else: self.logger.debug("Request not made from data: %r", data)

3、改写scrapy_redis项目

127.0.0.1:6379> lpush jianshu:start_urls https://www.jianshu.com/p/be20afe3475c (integer) 1 127.0.0.1:6379> keys * 1) "myspider_redis:items" 2) "dmoz:requests" 3) "jianshu:dupefilter" 4) "jianshu:requests" 5) "dmoz:dupefilter" 127.0.0.1:6379> type jianshu:requests zset 127.0.0.1:6379> zrange jianshu:requests 0 10

3.2、存入数据到虚拟机中的MongoDB数据库

class JianshuSpiderPipeline(object): def __init__(self): self.client = pymongo.MongoClient(host='127.0.0.1', port=27017) self.db = self.client['jianshu'] self.connection = self.db['article'] def process_item(self, item, spider): self.connection.save(item) return item

出现 由于目标计算机积极拒绝,无法连接。的错误时 查看是否设置虚拟机的端口转发 etc目录下的mongodb.conf文件是否修改ip为0.0.0.0,修改完成后重启服务service mongodb restart

最新回复(0)