浅谈深度优先和广度优先(scrapy-redis)
首先先谈谈深度优先和广度优先的定义
深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
| 深度优先搜索 | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
节点进行深度优先搜索的顺序 |
||||||||||||||
| 概况 | ||||||||||||||
|
广度优先搜索算法(英语:Breadth-First-Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。广度优先搜索的实现一般采用open-closed表。
| 广度优先搜索 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
节点进行广度优先搜索的顺序 |
||||||||||||
| 概况 | ||||||||||||
|
通俗的讲:
深度优先:一个一个节点往下找,不找兄弟节点,每一个深度一个节点,先进去的后出来
广度优先:横向取值,一个节点有关联其他的节点,一同被取出来,一个深度多个节点,先进去的先出来
在settings里面的配置:
from scrapy_redis.queue import PriorityQueue,FifoQueue,LifoQueue
先进先出:广度优先
SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.FifoQueue'
后进先出:深度优先
SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.LifoQueue'
优先级队列:
SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.PriorityQueue'
优先级队列里面也有深度优先和广度优先: requets.priority=1 广度优先
requets.priority=1 深度优先
实现原理:
from scrapy_redis import queue
prio=1
depth = response.meta['depth'] + 1
requets.priority-=depth*self.prio
每一次循环,depth加1
同一个深度可以找到很多url(兄弟节点)
如果是1的话,广度优先
广度优先:
depth 优先级
1 -1
1 -1
1 -1
2 -2
从深度为1的开始往下找,优先级也越大
重点:深度越小,优先级越小
def push(self, request):
"""Push a request"""
data = self._encode_request(request)
score = -request.priority##取反,注意
......
优先级队列:
放进队列里面:
反一下
1 1
1 1
1 1
2 2
......
print('这里优先级是',score)
print(request.meta.get('depth'))
# We don't use zadd method as the order of arguments change depending on
# whether the class is Redis or StrictRedis, and the option of using
# kwargs only accepts strings, not bytes.
self.server.execute_command('ZADD', self.key, score, data)
#按照分值来看
def pop(self, timeout=0):
"""
Pop a request
timeout not support in this queue class
"""
# use atomic range/remove using multi/exec
##开启事物
pipe = self.server.pipeline()
pipe.multi()
##取第一个值出来,拿出一个删除一个
pipe.zrange(self.key, 0, 0).zremrangebyrank(self.key, 0, 0)
results, count = pipe.execute()
if results:
return self._decode_request(results[0])
最终pop是按照这个优先级来取值的,优先级越小的越先被取出来,优先级从小多大取值
总结:就是深度越小,优先级越小,越先被取出来>>广度优先(先进先出,横向取值)
深度优先:
先进后出:一个一个节点的往下面执行
深度越大,优先级越小,越先被pop出来
深度优先类似,就不多说了
....................
浅谈深度优先和广度优先(scrapy-redis)的更多相关文章
- 浅谈 OpenResty,基于opebresty+redis进行实时线上限流
一.前言 我们都知道Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开 ...
- scrapy分布式浅谈+京东示例
scrapy分布式浅谈+京东示例: 学习目标: 分布式概念与使用场景 浅谈去重 浅谈断点续爬 分布式爬虫编写流程 基于scrapy_redis的分布式爬虫(阳关院务与京东图书案例) 环境准备: 下载r ...
- $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )
$.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...
- Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理
基于python+mysql浅谈redis缓存设计与数据库关联数据处理 by:授客 QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3 ...
- 第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理
第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理 网站树形结构 深度优先 是从左到右深度进行爬取的,以深度为准则从左到右的执行(递归方式实现)Scrapy默认 ...
- 十七 Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理
网站树形结构 深度优先 是从左到右深度进行爬取的,以深度为准则从左到右的执行(递归方式实现)Scrapy默认是深度优先的 广度优先 是以层级来执行的,(列队方式实现)
- 浅谈:Redis持久化机制(一)RDB篇
浅谈:Redis持久化机制(一)RDB篇 众所周知,redis是一款性能极高,基于内存的键值对NoSql数据库,官方显示,它的读效率可达到11万次每秒,写效率能达到8万次每秒,因为它基于内存以及存 ...
- 浅谈:Redis持久化机制(二)AOF篇
浅谈:Redis持久化机制(二)AOF篇 上一篇我们提及到了redis的默认持久化方式RDB,是一种通过存储快照数据方式持久化的机制,它在宕机后会丢失掉最后一次更新RDB文件后的数据,这也是由于它 ...
- 浅谈:redis的主从复制 + 哨兵模式
浅谈:redis的主从复制 + 哨兵模式 主从模式 在谈论redis的主从复制之前,我们先回想下mysql的主从搭建过程,第一步呢首先要在主库服务器中修改my.cnf,开启一下bin_log功能, ...
随机推荐
- extjs.net Combox赋值
1.直接赋值 ].Rows) //遍历获取两个值 { Ext.Net.ListItem listItem = new Ext.Net.ListItem(); //每次创建一个Ext.Net.ListI ...
- Newtonsoft.Json 的基本用法
Ø 前言 说起 C# 对 JSON 的操作(序列化与反序列化),大家都会想到 JavaScriptSerializer.DataContractJsonSerializer 与 Newtonsoft ...
- jquery实现图片上传前的预览
html代码 <div id="uploadPreview"></div> <input id="uploadImage" typ ...
- Restful API学习Day3 - DRF视图
视图 一.进化 class GenericView(APIView): """把视图中可能用到的配置和方法封装起来""" queryset ...
- Kaldi如何统计data数据集
统计时长 wav-to-duration scp:data/train/wav.scp ark,t:- 2>/dev/null|awk 'BEGIN{SUM=0}{SUM+=$2}END{pri ...
- Idea快捷操作
command+N 导入jar包 在方法体内部有for循环,在IntellJ中是输入fori,然后会有一个提示,选中需要的for循环即可 System.out.println();在IntellJ中是 ...
- 列式数据库~clickhouse问题汇总
一 简介:常见的clickhouse 问题汇总 二 问题系列 1 内存问题 Code: 241. DB::Exception: Received from localhost:9000, : ...
- 20165234 预备作业3 Linux安装及学习
一.基于VirtualBox虚拟机安装Ubuntu 这是我首次安装虚拟机,也是首次接触Linux系统.对于下学期要运用的这个操作系统,以及如何在自己的电脑上安装虚拟机,我还是有些期待和好奇的. 我一直 ...
- java ==、equals、hashcode有什么区别
1.== 用来比较两个对象的存储空间 2.equals是Object类提供的方法之一,每个java类都继承Object类,所以每一个对象都具有equals方法,所以在没有覆盖equals方法的情况下, ...
- 20165221 JAVA第五周学习心得
课本知识点 内部类与异常类 内部类:在一个类中定义另一个类 特点:外嵌类的成员在内部类仍然有效,内部类也可调用外嵌类的方法,内部类的类体不能声明类变量及类方法 非内部类不能是static类 匿名类:创 ...