Scrapy 增量式爬虫

https://blog.csdn.net/mygodit/article/details/83931009

https://blog.csdn.net/mygodit/article/details/83896412

https://blog.csdn.net/qq_39965716/article/details/81073015

一、定义

二、原理

  spider构造的第一个Request请求经由引擎交给了Scheduler,Scheduler中构造一个request对象,并将这个对象存入一个Scheduler的队列中,入队之前会生成一个对应的,唯一的指纹,下一个request对象入队之前,会先比对指纹是否已经存在,以此来达到request对象去重的目的。

  Scheduler中Request对象的初始化属性,其中dont_filter表示不去重,默认是False。所以scrapy框架默认是去重的。

 class Request(object_ref):
def __init__(self, url, callback=None, method='GET', headers=None, body=None,
cookies=None, meta=None, encoding='utf-8', priority=0,
dont_filter=False, errback=None, flags=None):

Rquest

爬虫组件Spider中,负责构造request对象是 start_requests(self) 函数。Spider构造的request对象修改了dont_filter属性。

源码如下:

def start_requests(self):
cls = self.__class__
if method_is_overridden(cls, Spider, 'make_requests_from_url'):
warnings.warn(
"Spider.make_requests_from_url method is deprecated; it "
"won't be called in future Scrapy releases. Please "
"override Spider.start_requests method instead (see %s.%s)." % (
cls.__module__, cls.__name__
),
)
for url in self.start_urls:
yield self.make_requests_from_url(url)
else:
for url in self.start_urls:
yield Request(url, dont_filter=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Scrapy去重的原理
Scrapy去重原理是通过sha1()加密request对象的url,method,body属性生成一个十六进制的40位随机字符串,称为指纹。将每个request对象对应的唯一指纹保存到Scheduler队列中,下次请求时,通过对比指纹,来达到request对象去重的目的。
生成指纹集合的源码如下:

def request_fingerprint(request, include_headers=None):
if include_headers:
include_headers = tuple(to_bytes(h.lower())
for h in sorted(include_headers))
cache = _fingerprint_cache.setdefault(request, {})
if include_headers not in cache:
fp = hashlib.sha1()
fp.update(to_bytes(request.method))
fp.update(to_bytes(canonicalize_url(request.url)))
fp.update(request.body or b'')
if include_headers:
for hdr in include_headers:
if hdr in request.headers:
fp.update(hdr)
for v in request.headers.getlist(hdr):
fp.update(v)
cache[include_headers] = fp.hexdigest()
return cache[include_headers]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
存储在Scheduler中的reqeust队列,是放在内存上的,如果服务器关闭,或者重启,内存中的缓存就会清空,下次请求就会继续访问原来发送过的请求。

增量式爬虫的意义就是将reques队列持久化存储,以此来达到永久性的缓存。

对此需要用到scrapy_redis(需要pip install scarpy_redis),将request对象的队列和指纹集合存储的位置替换成redis。如下图所示:

只需要在settings.py文件中添加一些配置,就能实现持久化去重的效果:

 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True # 添加redis链接
REDIS_URL = "redis://127.0.0.1:6379" # 或者使用下面的方式
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379 # 在pipeline中添加存储信息的scrapy_redis管道
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 400,
}

Scrapy 增量式爬虫的更多相关文章

  1. 基于Scrapy框架的增量式爬虫

    概述 概念:监测 核心技术:去重 基于 redis 的一个去重 适合使用增量式的网站: 基于深度爬取的 对爬取过的页面url进行一个记录(记录表) 基于非深度爬取的 记录表:爬取过的数据对应的数据指纹 ...

  2. 增量式爬虫 Scrapy-Rredis 详解及案例

    1.创建scrapy项目命令 scrapy startproject myproject 2.在项目中创建一个新的spider文件命令: scrapy genspider mydomain mydom ...

  3. 爬虫07 /scrapy图片爬取、中间件、selenium在scrapy中的应用、CrawlSpider、分布式、增量式

    爬虫07 /scrapy图片爬取.中间件.selenium在scrapy中的应用.CrawlSpider.分布式.增量式 目录 爬虫07 /scrapy图片爬取.中间件.selenium在scrapy ...

  4. 爬虫---scrapy分布式和增量式

    分布式 概念: 需要搭建一个分布式的机群, 然后在每一台电脑中执行同一组程序, 让其对某一网站的数据进行联合分布爬取. 原生的scrapy框架不能实现分布式的原因 调度器不能被共享, 管道也不能被共享 ...

  5. 爬虫 crawlSpider 分布式 增量式 提高效率

    crawlSpider 作用:为了方便提取页面整个链接url,不必使用创参寻找url,通过拉链提取器,将start_urls的全部符合规则的URL地址全部取出 使用:创建文件scrapy startp ...

  6. python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制

    CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...

  7. Scrapy 框架 增量式

    增量式: 用来检测网站中数据的更新情况 from scrapy.linkextractors import LinkExtractor from scrapy.spiders import Crawl ...

  8. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [三] 配置式爬虫

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 上一篇介绍的基本的使用方式,虽然自由度很高,但是编写的代码相对还是挺多.于是框 ...

  9. 增量式PID计算公式4个疑问与理解

    一开始见到PID计算公式时总是疑问为什么是那样子?为了理解那几道公式,当时将其未简化前的公式“活生生”地算了一遍,现在想来,这样的演算过程固然有助于理解,但假如一开始就带着对疑问的答案已有一定看法后再 ...

随机推荐

  1. 内网渗透神器xerosploit

    项目地址:https://github.com/LionSec/xerosploit 安装完成后直接在终端输入xerosploit打开 显示了本机的内网ip,mac地址,网关,网卡,输入help查看帮 ...

  2. pandas数据对齐

    Pandas的对齐运算 是数据清洗的重要过程,可以按索引对齐进行运算,如果没对齐的位置则补NaN,最后也可以填充NaN Series的对齐运算 1. Series 按行.索引对齐 示例代码: s1 = ...

  3. <%@ page import=""%>的用法

    转自:https://blog.csdn.net/huihui870311/article/details/455642111 <jsp:directive.page import=" ...

  4. idea写中文到mysql乱码

    idea中中文写入到mysql乱码 参考如下链接: https://segmentfault.com/q/1010000006174975/a-1020000006184639

  5. Timer中的重要函数

  6. python闭包和装饰器的理解

    闭包: 两个函数的嵌套,外部函数返回内部函数的引⽤,外部函数⼀定有参数 def 外部函数(参数): def 内部函数(): pass return 内部函数 他跟函数之间的区别: 1.格式两个函数嵌套 ...

  7. java StirngStringbufferStringbuild的区别

    java StirngStringbufferStringbuild的区别  String 1,Stirng是对象不是基本数据类型 2,String是final类,不能被继承.是不可变对象,一旦创建, ...

  8. LoadRunner Controller

    1.Controller的引入 1)需要Controller的原因?需要多个用户来模拟并发的时候. 2)一种强大的.成熟的工具的体现. 2. Controller的启动方式 1)LoadRunner ...

  9. 747. Largest Number At Least Twice of Others比所有数字都大两倍的最大数

    [抄题]: In a given integer array nums, there is always exactly one largest element. Find whether the l ...

  10. opennebula 创建镜像数据块

    {","csrftoken":"f5454a02dea7b4a7d5d50b482a762b57"}