当前位置: 首页 > news >正文

3.2 网站图的爬取路径

深度优先与广度优先方法都是遍历树的一种方法,但是网站的各个网页 之间的关系未必是树的结构,它们可能组成一个复杂的图形结构,即有回路

如果在前面的网站中每个网页都加一条Home的语句,让每个网页都能回到主界面,那么网站的关系就是一个有回路的图

1. 复杂的 Web网站


  1. books.html

<h3>计算机</h3>
<ul><li><a href="database.html">数据库</a></li><li><a href="program.html">程序设计</a></li><li><a href="network.html">计算机网络</a></li>
</ul>
  1. database.html

<h3>数据库</h3>
<ul><li><a href="mysql.html">MySQL数据库</a></li>
</ul>
<a href="books.html">Home</a>
  1. program.html

<h3>程序设计</h3>
<ul><li><a href="python.html">Python程序设计</a></li><li><a href="java.html">Java程序设计</a></li>
</ul>
<a href="books.html">Home</a>
  1. network.html

<h3>计算机网络</h3>
<a href="books.html">Home</a>
  1. mysql.html

<h3>MySQL数据库</h3>
<a href="books.html">Home</a>
  1. python.html

<h3>Python程序设计</h3>
<a href="books.html">Home</a>
  1. java.html

<h3>Java程序设计</h3>
<a href="books.html">Home</a>

这时,深度优先与广度优先方法要做一点改进可以用一个 python 中的列表 urls ;来记住已经访问过的网站,如果一个网址 url 没有访问过就访问它,并把 url 加到 urls 中保存起来,如果 url 已经访问过就不再访问了,这样就可以避免形成回路,导致无限循环。

2. 改进深度优先客户端程序


假定给定图 G 的初始状态是所有顶点均未曾访问过。在 G 中任选一顶点 v 为初始出发点(圆点),则深度优先遍历可以定义如下:

  • 首先访问出发点v,并将其标记为已访问;

  • 然后依次从 v 触发搜索 v 的每个邻接点 w 。

  • 若 w 未被曾访问过,则以 w 为新的出发点继续进行深度优先遍历,直至图中所有和原点 v 有路径相通的顶点(以称为原点可达的顶点)均已被访问为止。

图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是 尽可能先对纵深方向进行搜索。这种搜索方法称为深度优先搜索 (Depth-First Search)。相应地,用此方法遍历图就很自然地称之为图 的深度优先遍历,基本实现思想:

  • 访问顶点v;

  • 从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度 优先遍历;

  • 重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

使用递归程序

改进客户端程序 client1.py 如下:

# 使用递归的程序
from bs4 import BeautifulSoup
import urllib.requestdef spider(url):global urls  # 使用列表存储和标记已经访问过的节点if url not in urls:  # 未被访问过urls.append(url)try:data = urllib.request.urlopen(url)data = data.read()data = data.decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)links = soup.select("a")for link in links:href = link["href"]url = start_url + "/" + hrefspider(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000"
urls = []
spider(start_url)
print("The End")

使用栈的程序

改进客户端程序 client2.py 如下:

# 使用栈的程序
from bs4 import BeautifulSoup
import urllib.requestclass Stack:def __init__(self):self.st = []def pop(self):return self.st.pop()def push(self, obj):self.st.append(obj)def empty(self):return len(self.st) == 0def spider(url):global urlsstack = Stack()stack.push(url)while not stack.empty():url = stack.pop()if url not in urls:urls.append(url)try:data = urllib.request.urlopen(url)data = data.read()data = data.decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)links = soup.select("a")for i in range(len(links) - 1, -1, -1):href = links[i]["href"]url = start_url + "/" + hrefstack.push(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000"
urls = []
spider(start_url)
print("The End")

这两个程序结果一样,如下:

3. 改进广度优先客户端程序


图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。基本实现思想:

(1)顶点v入队列。
(2)当队列非空时则继续执行,否则算法结束。
(3)出队列取得队头顶点v;访问顶点v并标记顶点v已被访问。
(4)查找顶点v的第一个邻接顶点col。
(5)若v的邻接顶点col未被访问过的,则col入队列。
(6)继续查找顶点v的另一个新的邻接顶点col,转到步骤(5)。直到 顶点v的所有未被访问过的邻接点处理完。转到步骤(2)。

广度优先遍历图是以顶点v为起始点,由近至远,依次访问和v有路径相通 而且路径长度为1,2,……的顶点。为了使“先被访问顶点的邻接点”先 于“后被访问顶点的邻接点”被访问,需设置队列存储访问的顶点。

使用队列的程序

改进客户端程序 client3.py 如下:

# 使用队列的程序
from bs4 import BeautifulSoup
import urllib.requestclass Queue:def __init__(self):self.st = []def fetch(self):return self.st.pop(0)  # 出队列,弹出列表头的元素def enter(self, obj):  # 入队self.st.append(obj)def empty(self):return len(self.st) == 0def spider(url):global urlsqueue = Queue()queue.enter(url)while not queue.empty():url = queue.fetch()if url not in urls:try:urls.append(url)data = urllib.request.urlopen(url)data = data.read()data = data.decode()soup = BeautifulSoup(data, "lxml")print(soup.find("h3").text)links = soup.select("a")for link in links:href = link["href"]url = start_url + "/" + hrefif url not in urls:queue.enter(url)except Exception as err:print(err)start_url = "http://127.0.0.1:5000"
urls = []
spider(start_url)
print("The End")

程序运行结果如下:

相关文章:

3.2 网站图的爬取路径

深度优先与广度优先方法都是遍历树的一种方法&#xff0c;但是网站的各个网页 之间的关系未必是树的结构&#xff0c;它们可能组成一个复杂的图形结构&#xff0c;即有回路。如果在前面的网站中每个网页都加一条Home的语句&#xff0c;让每个网页都能回到主界面&#xff0c;那么…...

《SQL基础》12. SQL优化

SQL优化SQL优化数据插入insert优化大批量插入数据主键优化order by优化group by优化limit优化count优化count用法update优化SQL优化 数据插入 insert优化 如果我们需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化。 批量插入手动控制事务主键顺…...

fork之后是子进程先执行还是父进程先执行

CFS(完全公平调度器)是Linux内核2.6.23版本开始采用的进程调度器&#xff0c;它的基本原理是这样的&#xff1a;设定一个调度周期(sched_latency_ns)&#xff0c;目标是让每个进程在这个周期内至少有机会运行一次&#xff0c;换一种说法就是每个进程等待CPU的时间最长不超过这个…...

2023年java初级面试题(5道)

一、两个对象值相同(x.equals(y) true)&#xff0c;但却可有不同的hash code&#xff0c;这句话对不对&#xff1f;答&#xff1a;不对&#xff0c;如果两个对象x和y满足x.equals(y) true&#xff0c;它们的哈希码&#xff08;hash code&#xff09;应当相同。Java对于eqauls…...

【内网安全】——Linux权限维持

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 以后赚大钱座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日鸡汤&#xff1a; 钱至少对于现在的我来说&#xff0c;的确是万能的在…...

Linux 真实使用内存计算

获取Linux内存信息&#xff0c;可通过cat /proc/meminfo查看&#xff0c;比如&#xff0c;Ubuntu 20.04.5 LTS上会显示以下信息&#xff1a; leoyaDESKTOP-LMR:~$ cat /proc/meminfo MemTotal: 16017572 kB MemFree: 15637472 kB MemAvailable: 15533140 kB Bu…...

Unity Jobsystem ECS

简介随着ECS的加入&#xff0c;Unity基本上改变了软件开发方面的大部分方法。ECS的加入预示着OOP方法的结束。随着实体组件系统ECS的到来&#xff0c;我们在Unity开发中曾使用的大量实践方法都必须进行改变以适应ECS&#xff0c;也许不少人需要些时间适应ECS的使用&#xff0c;…...

Java中创建线程有哪几种方式

1.继承Thread类 总结&#xff1a;通过继承 Thread 类&#xff0c;重写 run() 方法&#xff0c;而不是 start() 方法 Thread 类底层实现 Runnable 接口类只能单继承 接口可以多继承2.实现Runnable接口 总结&#xff1a;通过实现 Runnable 接口,实现 run() 方法&#xff0c;依然…...

C++【string类用法详细介绍string类模拟实现解析】

文章目录string 类用法介绍及模拟实现一、string介绍二、string类常用接口1. string类对象的常见构造接口2.string类对象的常见容量接口3.string类对象的常见修改接口4. string类对象的常见访问及遍历接口5.string其他接口1.不常用查找接口2.字符替换3.字符串拼接4.字符串排序5…...

常见的开发模型和测试模型

软件的生命周期软件开发阶段的生命周期需求分析->计划->设计->编码->测试->运维软件测试阶段的生命周期需求分期->测试计划->测试设计与开发->执行测试->测试评估开发模型瀑布模型可以看到,这个模型和我们上面的软件开发生命周期很相似采用的是线性…...

印度和印度尼西亚有什么关系吗?

印度和印度尼西亚&#xff0c;这两个国家很多人都比较熟悉。因为两国都是人口大国&#xff0c;而且经济总量也比较高&#xff0c;在全球还是有很大影响的。不过很多人刚看到这两个国家的时候&#xff0c;都会觉得这两个国家肯定有什么关系&#xff0c;要不然国名也不会这么像。…...

单调栈(C/C++)

目录 1. 单调栈的定义 2. 单调栈的常见用途 3. 案例分析 3.1 暴力解法 3.2 单调栈 4. 单调栈总结 1. 单调栈的定义 单调栈顾名思义&#xff0c;就是栈内的元素是单调的。根据栈内元素的单调性的不同&#xff0c;可以分为&#xff1a; 单调递增栈&#xff1a;栈内元素是单…...

算法设计与智能计算 || 专题一: 算法基础

专题一: 算法基础 文章目录专题一: 算法基础1. 算法的定义及特点1.1 算法的基本特征1.2 算法的基本要素1.3 算法的评定2 算法常见执行方法2.1 判断语句2.2 循环语句2.3 综合运用3. 计算复杂度4. 代码的重用5. 类函数的定义与使用5.1 定义类5.2 调用类函数1. 算法的定义及特点 …...

用javascript分类刷leetcode13.单调栈(图文视频讲解)

239. 滑动窗口最大值 (hard) 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,…...

英语基础语法学习(B站英语电力公司)

1. 句子结构 五大基本句型&#xff1a; 主谓主谓宾主谓宾宾主谓宾宾补主系表 谓语&#xff1a; 一般来说&#xff0c;谓语是指主语发出的动作。&#xff08;动词&#xff09;但是很多句子是没有动作的&#xff0c;但是还是必须要有谓语。&#xff08;此时需要be动词&#x…...

【计算机网络】网络层IP协议

文章目录一、认识IP协议二、IP协议头部格式三、IP地址划分1. IP地址分类2. 子网划分四、IP地址数量危机1. IP地址的数量限制2. NAT技术五、私网IP和公网IP六、路由1. 认识路由2. 路由表生成算法一、认识IP协议 IP协议是Internet Protocol&#xff08;互联网协议&#xff09;的…...

Eclipse快捷键大全

编辑类快捷键Ctrl1: 快速修复(最经典的快捷键, 可以解决很多问题, 比如import类、try catch包围等)CtrlShiftF: 格式化当前代码CtrlShiftM: 添加类的import导入CtrlShiftO: 组织类的导入(既有CtrlShiftM的作用,又可以去除没用的导入, 一般用这个导入包)CtrlY: 重做(与CtrlZ相反…...

JavaScript 高级2 :构造函数和原型 d331702016e84f54b3594ae05e0eeac

JavaScript 高级2 &#xff1a;构造函数和原型 Date: January 16, 2023 Text: 构造函数和原型、继承、ES5中的新增方法 目标 能够使用构造函数创建对象 能够说出原型的作用 能够说出访问对象成员的规则 能够使用 ES5新增的一些方法 构造函数和原型 概述 在典型的 OOP 的…...

maven-war-plugin插件 overlays maven-war-plugin翻译

说明 翻译maven-war-plugin插件的部分内容 官方地址为&#xff1a;https://maven.apache.org/plugins/maven-war-plugin/index.html Overview 概述 Introduction 介绍 Apache Maven WAR Plugin apache maven war 插件 The WAR Plugin is responsible for collecting all artifa…...

【数据结构】初识二叉树(二叉树的入门知识)

初识二叉树一、树概念及结构1、树的概念2、树的相关概念3、树的表示4、树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09;二、二叉树概念及结构1、概念2、特殊的二叉树3、二叉树的性质4、二叉树的存储结构三、结语一、树概念及结构 1、树的概念 树是一种非线…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...