Python爬虫 - 理解深度优先和广度优先

 

爬虫有三大策略——深度优先,广度优先以及不重复抓取

在爬虫系统中,待抓取URL队列是很重要的一部分,待抓取URL队列中的URL以什么样的顺序排队列也是一个很重要的问题,因为这涉及到先抓取哪个页面,后抓取哪个页面。而决定这些URL排列顺序的方法,叫做抓取策略。下面是常用的两种策略:深度优先、广度优先 。

 

               图1              

 

深度优先

深度优先是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续追踪链接,通过图一进行理解。

深度优先遍历原理:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历(我们前面使用的是先序遍历)

深度优先它在图一的爬取的顺序:     A-B-D-E-I-C-F-G-H (递归实现)

注:scrapy默认采用的是深度优先算法

深度优先算法的实现(伪代码):

广度优先

广度优先,有人也叫宽度优先,是指将新下载网页发现的链接直接插入到待抓取URL队列的末尾,也就是指网络爬虫会先抓取起始页中的所有网页,然后在选择其中的一个连接网页,继续抓取在此网页中链接的所有网页。

广度优先遍历原理:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。

广度优先在图一的的爬取顺序为:A-B-C-D-E-F-G-H-I (队列实现)

广度优先代码的实现(伪代码):

两者优缺点:

  深度优先搜素算法:不全部保留结点,占用空间少;有回溯操作(即有入栈、出栈操作),运行速度慢。

       广度优先搜索算法:保留全部结点,占用空间大; 无回溯操作(即无入栈、出栈操作),运行速度快。

  通常深度优先搜索法不全部保留结点,扩展完的结点从数据库中弹出删去,这样,一般在数据库中存储的结点数就是深度值,因此它占用空间较少。所以,当搜索树的结点较多,用其它方法易产生内存溢出时,深度优先搜索不失为一种有效的求解方法。

  广度优先搜索算法,一般需存储产生的所有结点,占用的存储空间要比深度优先搜索大得多,因此,程序设计中,必须考虑溢出和节省内存空间的问题。但广度优先搜索法一般无回溯操作,即入栈和出栈的操作,所以运行速度比深度优先搜索要快些。

      爬虫深度优先搜索优点是能遍历一个Web 站点或深层嵌套的文档集合;缺点是因为Web结构相当深,,有可能造成一旦进去,再也出不来的情况发生

 

广度优先是爬虫中使用最广泛的一种爬虫策略,主要原因有三点: 
1. 重要的网页往往离种子比较近。例如我们打开新闻网站的时候往往是最热门的新闻,随着不断的深入冲浪,所看到的网页的重要性越来越低。 
2. 万维网的实际深度最多能达到17层,但到达某个网页总存在一条很短的路径。而广度优先遍历会以最快的速度到达这个网页。 
3. 广度优先有利于多爬虫的合作抓取,多爬虫合作通常先抓取站内链接,抓取的封闭性很强。

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
深度优先搜索和广度优先搜索是图遍历的两种算法,它们在遍历顺序和实现方法上有所不同。 深度优先搜索(DFS)是沿着一条路径不断往下进行深度搜索。它选择最新成为候补的顶点,沿着新发现的路径不断深入搜索。在Python中,可以使用以下代码实现深度优先搜索: ```python def dfs(adj, start): visited = set() stack = [[start, 0]] while stack: (v, next_child_idx) = stack[-1] if (v not in adj) or (next_child_idx >= len(adj[v])): stack.pop() continue next_child = adj[v][next_child_idx] stack[-1][1 = 1 if next_child in visited: continue print(next_child) visited.add(next_child) stack.append([next_child, 0]) graph = {1: [4, 2], 2: [3, 4], 3: [4], 4: [5]} dfs(graph, 1) ``` 广度优先搜索(BFS)是从根节点开始,沿着树的宽度遍历树的节点。它选择最早成为候补的顶点,从离起点近的地方开始按顺序搜索。在Python中,可以使用以下代码实现广度优先搜索: ```python import queue def bfs(adj, start): visited = set() q = queue.Queue() q.put(start) while not q.empty(): u = q.get() print(u) for v in adj.get(u, []): if v not in visited: visited.add(v) q.put(v) graph = {1: [4, 2], 2: [3, 4], 3: [4], 4: [5]} bfs(graph, 1) ``` 这些代码可以让你在给定图的情况下,使用深度优先广度优先算法进行搜索并输出结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Python广度优先深度优先](https://blog.csdn.net/m0_50481455/article/details/118695003)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [深度优先算法和广度优先算法(python)](https://blog.csdn.net/qq_41661056/article/details/95605803)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值