Scrapy框架 增量式、分布式爬虫

news2024/11/26 16:28:52

文章目录

    • Scrapy框架
      • 1.增量爬虫
      • 2.分布式爬虫

Scrapy框架

1.增量爬虫

  • 实现思路
利用redis集合数据类型
1.获取到url后进行判断 是否重复???
2.第一次爬取到数据,爬取完成写入该记录...
(两个点: 必须要没有爬过的数据 在这个基础之上做
(1)数据准备入到管道之前
(2)数据入库之前
)
优点:
Redis查询速度快 相比: Mysql 文件 Mongdb ...

  • 信号代码实现 配置打开关闭
@classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        s = cls()
        s._set_crawler(crawler)  # -> 参考父类中的写法
        # 定义两个信号
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
        return s

    def spider_opened(self, spider):
        self.conn = redis.Redis(host="127.0.0.1", port=6379, db=3, password="123456", decode_responses=True)

    def spider_closed(self, spider):
        self.conn.save()  # 存储到硬盘
        self.conn.close()  # 关闭连接
  • 集合去重逻辑
if self.conn.sismerber(key, href?):
    continue

   成功请求获取数据 
	添加该记录 url相当于就是主键  or 管道pipelines设置  process_item()
    open_spider/ close_spider 两个hook方法 上下文管理
    self.conn.sadd(key, url) 

yield {
    xxx: yyy
}
  • 定时任务 while + 进程(scrapy会帮我们自动杀死process)
import time
from scrapy.cmdline import execute
from multiprocessing import Process
from datetime import datetime
def task():
    # sys.exit(0)
    execute("scrapy crawl fuck".split())

if __name__ == '__main__':
    # 定时任务 time.seep()
    while 1:
        process  = Process(target=task)
        process.start()
        print(f"正在等待执行中..... 当前时间=====> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        time.sleep(60 * 2) # 两分钟一次
        process.join()

2.分布式爬虫

在这里插入图片描述

  • 核心思想
利用多个scrapy程序对同一个任务进行分解,模拟出多个worker干同一任务的场景。直到完成所有的任务。
1.单个scrapy实现去重逻辑: set() + 指纹sha1 创建request的时候设置的是否去重?
2.多个scrapy实现去重逻辑: 共享一个Redis 集合 + 队列(列表lpush brpop) 消息队列
针对处理我们的耗时任务 各个worker之间是独立的不会产生影响!

核心: 依赖Redis  MQ其实也可以 Kafka Celery 处理异步任务的框架 
(1)去重集合
(2)请求队列
  • 简单配置Redis分布式爬虫

    # settings.py
    # 调度器类
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 过滤器类.
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    #  save操作
    SCHEDULER_PERSIST = True 
    # 管道 数据存储在Redis里面
    ITEM_PIPELINES = {
        # 配置redis的pipeline  可用可不用
        'scrapy_redis.pipelines.RedisPipeline': 301  
    }
    # Redis server
    REDIS_HOST = "localhost"
    REDIS_PORT = 6379
    REDIS_DB = 4
    REDIS_PARAMS = {
        "password": ""
    }
    
    # spider文件 爬虫核心文件...
    pip install scrapy-redis
    1.更换继承关系
    2. 干掉这个start_urls
    3. 更换为redis_key 起始url,相当于就是任务id ... 
    [注意] 给Redislpsuh的时候注意推url  该url 请求后的逻辑会返回resp 
    数据处理的逻辑必须一致!!!
    
    from scrapy_redis.spiders import RedisSpider
    class XxxSpider(RedisSpider):
        name = "nb_cqie"
        redis_key = "cqie_pro:item"
    

    [注意]

在这里插入图片描述

  • 调度器源码分析

    • 初始化调度器
      在这里插入图片描述

    • 核心代码执行流程
      在这里插入图片描述
      重复过滤器对象 几个队列类…

    • open函数
      在这里插入图片描述

在这里插入图片描述

close

在这里插入图片描述

​ 入队逻辑
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

指纹运算 代码分析: 参数 request 请求对象: url method body 等等进行签名

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

请求对象里面一般携带了哪些参数????
request = Request(url, headers, callback, dont_filter,cookies,method, meta,)
入队逻辑: 根据dont_filter判断 短路逻辑   xx and xxx 
        if not request.dont_filter and self.df.request_seen(request): 
            return False
代码解读:
(1) dont_filter False => 去重
not request.dont_filter => True 去重就判断是否是否重复???
执行: self.df.request_seen(request)  过滤器判断
1.如果指纹存在 True 条件: True and True : return False 跳过

2.如果指纹不存在 None/False 条件: True and False : return True 继续请求
request_seen() 校验该请求是否已经请求过了 :返回True/Fasle
指纹:存储在内存里面 集合数据类型自动去重: 算法:sha1 .....

伪代码模型:
if 是否去重 and 判断是否存在(根据指纹,set()): True 执行判断逻辑
	return Fasle 不玩了...
继续干...
将该请求添加到请求队列 给引擎 然后下载器 网络请求....

  • Pycharm配置并行程序

    • 清空运行栈

在这里插入图片描述

  • 重新配置运行
    在这里插入图片描述

  • 模板允许并行执行
    在这里插入图片描述

  • 并行 多个进程同时执行

在这里插入图片描述

  • 推送任务

    lpush key cqie_pro:item https://www.cqie.edu.cn/html/3/tzgg/Index.shtml
    
    

    程序执行结果:

在这里插入图片描述

Redis存储数据:

在这里插入图片描述

Redis分布式爬虫效果:
(1)你只需要往里面put任务基于消息队列 scrapy程序监听到消息后 直接执行 各个节点独立。
(2)支持断点续爬 和增量爬虫本质一样,利用Redis set数据结构 自动过滤掉重复请求
(3) 共享调度器 => Redis
(4) 同步 -> 异步

  • 版本

    pip install scrapy == 2.5.1
    pip install scrapy-redis==0.7.2
    

布隆过滤器:

​ 平时, 我们如果需要对数据进行去重操作可以有以下方案:

1. 直接用set集合来存储url. (最low的方案)
2. 用set集合存储hash过的url. scrapy默认
3. 用redis来存储hash过的请求, scrapy-redis默认就是这样做的. 如果请求非常非常多. redis压力是很大的.
4. 用布隆过滤器. 

布隆过滤器的原理: 其实它里面就是一个改良版的bitmap. 何为bitmap,.

假设我提前准备好一个数组, 然后把源数据经过hash计算. 会计算出一个数字. 我们按照下标来找到该下标对应的位置. 然后设置成1.

a = 李嘉诚
b = 张翠山
....

[0],[0],[0],[0],[0],[0],[0],[0],[0]  10个长度数组

hash(a) => 3
hash(b) => 4

[0],[0],[0],[1],[1],[0],[0],[0],[0] 
# 我想找'张三'
hash('张三') => 6

# 去数组中找6位置的数字。 是0,则不存在'张三'

# 找的时候依然执行该hash算法. 然后直接去找对应下标的位置看看是不是1. 是1就有, 不是1就没有

这样有个不好的现象. 容易误判. 如果hash算法选的不够好. 很容易搞错. 那怎么办. 多选几个hash算法

a = 李嘉诚
b = 张翠山

[0],[0],[0],[0],[0],[0],[0],[0],[0],[0]

hash1(a) = 3
hash2(a) = 4

hash1(b) = 2
hash2(b) = 5

[0],[0],[1],[1],[1],[1],[0],[0],[0],[0]

# 找的时候, 重新按照这个hash的顺序, 在重新执行一遍. 依然会得到2个值. 分别去这两个位置看是否是1. 如果全是1, 就有,  如果有一个是0, 就没有. 

在scrapy-redis中想要使用布隆过滤器是非常简单的. 你可以自己去写这个布隆过滤器的逻辑. 不过我建议直接用第三方的就可以了


# 安装布隆过滤器
pip install scrapy_redis_bloomfilter
# 配置即可...
# 去重类,要使用 BloomFilter 请替换 DUPEFILTER_CLASS
DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.dupefilter.RFPDupeFilter"
# 哈希函数的个数,默认为 6,可以自行修改
BLOOMFILTER_HASH_NUMBER = 6
# BloomFilter 的 bit 参数,默认 30,占用 128MB 空间,去重量级 1 亿
BLOOMFILTER_BIT = 30	
```python

# 安装布隆过滤器
pip install scrapy_redis_bloomfilter
# 配置即可...
# 去重类,要使用 BloomFilter 请替换 DUPEFILTER_CLASS
DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.dupefilter.RFPDupeFilter"
# 哈希函数的个数,默认为 6,可以自行修改
BLOOMFILTER_HASH_NUMBER = 6
# BloomFilter 的 bit 参数,默认 30,占用 128MB 空间,去重量级 1 亿
BLOOMFILTER_BIT = 30	

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/629560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python实现计算器:从入门到实现

Python实现计算器:从入门到实现 计算器是计算机科学中最基础并且实用的东西之一。Python作为一种高级编程语言,它可以用于编写一个功能完整的计算器。在本文中,我们将介绍Python如何实现一个简单的、交互式的计算器,通过使用基本…

【MySQL 数据库】7、SQL 优化

目录 一、插入数据优化(1) insert 语句① 批量插入数据② 手动控制事务③ 主键顺序插入,性能要高于乱序插入 (2) load 大批量插入数据【☆❀ 二、主键优化(1) 数据组织形式(2) 页分裂(3) 页合并(4) 主键设计原则 三、orber by 优化四、group by 优化五、limit 优化&…

chatgpt赋能python:Python怎么五个一行输出?

Python怎么五个一行输出? 在Python中,实现五个一行输出并不难,只需要使用循环语句即可。下面,我们将介绍如何使用Python实现五个一行输出。 实现方法 首先,我们需要定义一个包含一定数量元素的列表或字符串。然后&a…

chatgpt赋能python:Python中如何生成随机浮点数?

Python中如何生成随机浮点数? 随机数在计算机编程中常常使用,而在Python中,我们可以使用内置的random模块来产生随机数。不同于整数随机数,如果想要产生浮点数的随机数,我们就需要进行一些额外的操作。 产生浮点数类…

Baumer工业相机堡盟工业相机如何使用BGAPISDK控制相机数据流的开启和关闭(C++)

Baumer工业相机堡盟工业相机如何使用BGAPISDK控制相机数据流的开启和关闭(C) Baumer工业相机Baumer工业相机BGAPI SDK的技术背景Baumer工业相机使用BGAPISDK控制相机数据流的方式1.引用合适的类文件2.使用BGAPISDK控制相机数据流的方式2.使用BGAPISDK控制…

Pascal Voc 2007 2012

1、简介 PASCAL 全称:Pattern Analysis, Statical Modeling and Computational Learning PASCAL VOC(The PASCAL Visual Object Classes )是一个经典的计算机视觉数据集,由牛津大学、马里兰大学和微软剑桥研究院的研究人员创建的…

HiveSQL初级题目

文章目录 Hive SQL题库(初级)第一章 环境准备1.1 建表语句1.2 数据准备1.3 插入数据 第二章 简单查询2.1 查找特定条件2.1.1 查询姓名中带“冰”的学生名单2.1.2 查询姓“王”老师的个数2.1.3 检索课程编号为“04”且分数小于60的学生的课程信息,结果按分数降序排列…

chatgpt赋能python:Python如何保存文件到文件夹?

Python如何保存文件到文件夹? Python是一种高级编程语言,广泛应用于数据科学、网络编程、自动化任务等领域。其中,保存文件到文件夹是Python编程中的重要功能。本文将介绍Python如何保存文件到文件夹的方法,包括如何创建文件夹和…

动态网站JSP技术

文章目录 零、本节学习目标一、JSP概述(一)什么是JSP1、JSP的概念2、JSP的特征(二)编写第一个JSP1、创建Web项目2、修改Artifact名称,重新部署项目3、创建欢迎JSP页面4、启动服务器,查看结果 二、JSP基本语…

chatgpt赋能python:Python怎么产生方波?

Python怎么产生方波? 随着科技的发展,数字信号处理在各个领域都有广泛的应用,产生方波是其中一个基础的信号处理技术。在Python中,可以通过一些简单的代码来产生方波信号。本文将介绍如何使用Python产生方波。 什么是方波信号&a…

牛客小白赛复盘] 牛客小白月赛74

[牛客小白赛复盘] 牛客小白月赛74 总结A 简单的整除1. 题目描述2. 思路分析3. 代码实现 B 整数划分1. 题目描述2. 思路分析3. 代码实现 C 传送阵1. 题目描述2. 思路分析3. 代码实现 D 修改后的和1. 题目描述2. 思路分析3. 代码实现 E 幼稚园的树21. 题目描述2. 思路分析3. 代码…

一分钟学一个 Linux 命令 - tar

前言 大家好,我是 god23bin。今天给大家带来的是 Linux 命令系列,每天只需一分钟,记住一个 Linux 命令不成问题。今天,我们要介绍的是一个常用且强大的命令:tar。 什么是 tar 命令? tar 是 tape archive…

C语言经典题目(三)

C站的小伙伴们,大家好呀!😊😊✨✨这一篇是C语言之经典题目篇,除程序设计,还有一些不错的程序分析,快来和我一起进入C语言的世界吧!✨✨✨ 💕C语言其他刷题篇在这里哦&…

【Python程序设计】——重点题目(期末不挂科)

课本: 目录 🕒 1. 控制结构🕒 2. 数据类型🕒 3. 函数🕒 4. 文件操作🕒 5. 面向对象🕒 6. Excel操作🕒 7. 实验课题目合集🕒 8. 思政题 🕒 1. 控制结构 【例…

chatgpt赋能python:Python怎么二次安装?

Python怎么二次安装? 介绍 Python作为一种广泛应用的编程语言,其安装也是极其简单。只需要在Python官网上下载对应版本的安装包,并按照提示进行安装即可。但是,如果你需要二次安装Python,比如更新到新的版本或者将Py…

百度、头条、360、搜狗下拉拓词及长尾关键词挖掘-批量多线程

百度、头条、360、搜狗下拉拓词及长尾关键词挖掘软件介绍: 1、在如今竞争激烈的互联网时代,作为SEO站长,我们都知道一个事实:流量就是金钱!而要想在海量信息中脱颖而出,我们需要借助一些强大的工具来帮助我…

OpenMMLab-AI实战营第二期——4-1.目标检测与MMDetection

文章目录 1. 目标检测的基本范式1.0-1 目标检测简介1.0-2 基本概念1.1 滑窗1.1.1 滑窗基本思想1.1.2 滑窗效率问题改进1.1.3 感受野计算 1.2-1 使用卷积实现密集预测1.2.1 在特征图上进行密集预测1.2.2 边界框回归1.2.3 非极大值抑制(Non-Maximum Suppression&#…

chatgpt赋能python:Python入门:如何下载和安装JupyterNotebook

Python入门:如何下载和安装Jupyter Notebook Jupyter Notebook是Python编程必备的工具之一,它可以帮助你快速地编写和测试Python代码。在这篇文章中,我们将向你展示如何下载和安装Jupyter Notebook。如果你是一名Python入门者,这…

神经网络:CNN中的filter,kernel_size,strides,padding对输出形状的影响

输入数据在经过卷积层后,形状一般会发生改变,而形状的变化往往与以下四个超参数有关。 1,filter(out_channel) 该超参数控制着输入数据经过卷积层中需要与几个卷积核进行运算,而输入数据与每个卷积核进行…

【P57】JMeter 保存响应到文件(Save Responses to a file)

文章目录 一、保存响应到文件(Save Responses to a file)参数说明二、准备工作三、测试计划设计 一、保存响应到文件(Save Responses to a file)参数说明 可以将结果树保存到文件 使用场景:当结果太大,使…