Python灰帽编程——网页信息爬取

文章目录

  • 网页信息爬取
    • 1. 相关模块
      • 1.1 requests 模块
        • 1.1.1 模块中的请求方法
        • 1.1.2 请求方法中的参数
        • 1.1.3 响应对象中属性
      • 1.2 RE 模块
        • 1.2.1 匹配单个字符
        • 1.2.2 匹配一组字符
        • 1.2.3 其他元字符
        • 1.2.4 核心函数
    • 2. 网页信息爬取
      • 2.1 获取网页HTML 源代码
      • 2.2 提取图片地址
      • 2.3 下载图片
      • 2.4 完整脚本
    • 3. requests 模块基本用法
      • 3.1 获取浏览器指纹
      • 3.2 发送GET 参数
      • 3.3 发送POST 参数
      • 3.4 文件上传
        • 3.4.1 注意事项
      • 3.5 服务器超时

网页信息爬取

1. 相关模块

1.1 requests 模块

requests 模块:主要是用来模拟浏览器行为,发送HTTP 请求,并处理HTTP 响应的功能。

import requests     # 被认为,最贴近与人的操作的模块
import urllib
import urllib2
import urllib3

requests 模块处理网页内容的基本逻辑:

  • 定义一个URL 地址。
  • 发送HTTP 请求。
  • 处理HTTP 响应。
1.1.1 模块中的请求方法
请求方法说明
requests.get()常规的请求方法 (GET 方法)
requests.post()带有请求正文的 (POST 方法)
requests.head()只返回响应头部,没有响应正文
requests.options()测试服务器所支持的方法
requests.put()向服务器写入文件
requests.delete()请求删除服务器端文件
1.1.2 请求方法中的参数
参数名字参数含义
url请求URL 地址
headers自定义请求头部
params发送GET 参数
data发送POST 参数
timeout请求延时
files文件上传数据流
1.1.3 响应对象中属性
方法名解释
response.text响应正文(文本方式)
response.content响应正文(二进制)
response.status_code响应状态码
response.url发送请求的URL 地址
response.headers响应头部
response.request.headers请求头部
response.cookiescookie 相关信息

1.2 RE 模块

从网页内容中提取图片地址。

正则表达式(RE),是一些由字符和特殊符号组成的字符串,它们能按某种模式匹配一系列有相似特征的字符串。

  • 从哪一个字符串中搜索什么内容。
  • 规则是什么(模式问题)。
>>> import re
>>> s = "I say food not Good"
>>> re.findall('ood',s)
['ood', 'ood']
>>> re.findall(r"[fG]ood", s)
['food', 'Good']
>>> re.findall(r"[a-z]ood", s)
['food']
>>> re.findall(r"[A-Z]ood", s)
['Good']
>>> re.findall(r"[0-9a-zA-Z]ood", s)
['food', 'Good']
>>> re.findall(r"[^a-z]ood",s)
['Good']
>>> re.findall('.ood',s)
['food', 'Good']
>>> re.findall(r'food|Good|not',s)
['food', 'not', 'Good']
>>> re.findall(r".o{1,2}.", s)
['food', 'not', 'Good']
>>> re.findall('o*',s)
['', '', '', '', '', '', '', 'oo', '', '', '', 'o', '', '', '', 'oo', '', '']
>>> >>> s = "How old are you? I'm 24!"
>>> re.findall(r"[0-9]{1,2}", s)
['24']
>>> re.findall(r"\d{1,2}", s)
['24']
>>> re.findall(r"\w", s)
['H', 'o', 'w', 'o', 'l', 'd', 'a', 'r', 'e', 'y', 'o', 'u', 'I', 'm', '2', '4']
>>> >>> s = 'I like google not ggle goooogle and gogle'
>>> re.findall('o+',s)
['oo', 'o', 'oooo', 'o']
>>> re.findall('go+',s)
['goo', 'goooo', 'go']
>>> re.findall('go+gle',s)
['google', 'goooogle', 'gogle']
>>> re.findall('go?gle',s)
['ggle', 'gogle']
>>> re.findall('go{1,2}gle',s)
['google', 'gogle']
>>>
1.2.1 匹配单个字符
记号说明
.匹配任意单个字符(换行符除外)\. 表示真正的
[…x-y…]匹配字符集合里的任意单个字符
[^…x-y…]匹配不在字符组里的任意单个字符
\d匹配任意数字,与[0-9] 同义
\w匹配任意数字、字母、下划线,与[0-9a-zA-Z_] 同义,无法匹配特殊符号
\s匹配空白字符,与[\r\v\f\t\n] 同义
1.2.2 匹配一组字符
记号说明
字符串匹配字符串值
字符串1|字符串2匹配字符串1或字符串2
*左邻第一个字符出现0 次或无穷次
+左邻第一个字符最少出现1 次或无穷次
?左邻第一个字符出现0 次或1 次
{m,n}左邻第一个字符出现最少m 次最多n 次
1.2.3 其他元字符
记号说明
^匹配字符串的开始 集合取反
$匹配字符串的结尾
\b匹配单词的边界,单词包括\w 中的内容
()对字符串分组(单独匹配括号中的字符)
\数字匹配已保存的子组
1.2.4 核心函数
核心函数说明
re.findall()在字符串中查找正则表达式的所有(非覆盖)出现;返回一个匹配对象的列表。
re.match()尝试用正则表达式模式从字符串的开头匹配 如果匹配成功,则返回一个匹配对象 否则返回None
re.search()在字符串中查找正则表达式模式的第一次出现 如果匹配成,则返回一个匹配对象 否则返回None
re.group()使用match 或者search 匹配成功后,返回的匹配对象 可以通过group() 方法获取得匹配内容
re.finditer()和findall() 函数有相同的功能,但返回的不是列表而是迭代器 对于每个匹配,该迭代器返回一个匹配对象
re.split()根据正则表达式中的分隔符把字符分割为一个列表,并返回成功匹配的列表字符串也有类似的方法,但是正则表达式更加灵活
re.sub()把字符串中所有匹配正则表达式的地方换成新的字符串
>>> m = re.match('goo','I like google not ggle goooogle and gogle')
>>> type(m)
<class 'NoneType'>
>>> m = re.match('I','I like google not ggle goooogle and gogle')
>>> type(m)
<class 're.Match'>
>>> m.group()
'I'
>>> m = re.search('go{3,}','I like google not ggle goooogle and gogle')
>>> m.group()
'goooo'
>>> m = re.finditer('go*','I like google not ggle goooogle and gogle')
>>> list(m)
[<re.Match object; span=(7, 10), match='goo'>, <re.Match object; span=(10, 11), match='g'>, <re.Match object; span=(18, 19), match='g'>, <re.Match object; span=(19, 20), match='g'>, <re.Match object; span=(23, 28), match='goooo'>, <re.Match object; span=(28, 29), match='g'>, <re.Match object; span=(36, 38), match='go'>, <re.Match object; span=(38, 39), match='g'>]
>>> m = re.split('\.|-','hello-world.ajest')
>>> m
['hello', 'world', 'ajest']
>>> s = "hi x.Nice to meet you, x."
>>> s = re.sub('x','WUHU',s)
>>> s
'hi WUHU.Nice to meet you, WUHU.'
>>>

2. 网页信息爬取

通过python 脚本爬取网页图片:

  • 获取整个页面所有源码。
  • 从源码中筛选出图片的地址。
  • 将图片下载到本地。

2.1 获取网页HTML 源代码

# 01 - 获取网页源代码.pyimport requestsurl = "http://192.168.188.187/pythonSpider/"# 定义了一个请求头(headers)字典。请求头包含了一些信息,例如用户代理(User-Agent),用于模拟浏览器发送请求。
headers = {"User-Agent":   "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36"
}# 接收一个URL作为参数,并利用requests.get()方法发送GET请求获取网页内容。
def getHtml(url):res = requests.get(url = url, headers = headers)# 显示页面的编码print(res.encoding)# 字符串以二进制的形式显示return res.content# 调用getHtml函数并打印返回的HTML内容。
print(getHtml(url = url).decode("utf8"))

image-20230920193752822

2.2 提取图片地址

网页中的图片地址如下:

image-20230920194303080

# 02 - 提权图片地址.py
import requests
import reurl = "http://192.168.188.187/pythonSpider/"headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0"
}# 获取页面源码
def get_html(url):res = requests.get(url =url,headers=headers)# 字符串以二进制的形式返回return res.content# 从源码中获取图地址
# 利用正则表达式匹配出HTML中的图片路径并返回列表。
def get_html_path_list(html):img_path_list = re.findall(r"style/\w*\.jpg",html)return img_path_list# 在主程序中调用getHtml函数获取网页内容
html = get_html(url = url)# 将其解码为字符串,然后将解码后的内容传递给getImgPathList函数。
img_path_list = get_html_path_list(html.decode())# 获取图片路径列表。
for imgPath in img_path_list:img_url = url + imgPathprint(img_url)

image-20230920193842006

2.3 下载图片

# 03 - 下载图片.pyimport requests# 定义了一个URL变量,指定要请求的目标网址。
url = "http://192.168.188.187/pythonSpider/"# 定义了一个图片路径变量,以及一个完整的图片URL,通过拼接URL和图片路径得到。
img_path = "style/u401307265719758014fm173s0068CFB1485C3ECA44B8C5E5030090F3w21.jpg"img_url = url + img_pathheaders = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0"
}def get_html(url):res = requests.get(url = url, headers = headers)return res.content# 接收一个图片保存路径和图片URL作为参数。在函数内部,打开文件以二进制写入模式,利用get_html函数获取图片内容,并将其写入文件。
def save_img(img_save_path, img_url):with open(img_save_path, "wb") as f:f.write(get_html(url = img_url))# 在主程序中调用save_img函数,传递图片保存路径和图片URL,将图片内容下载并保存到本地。
save_img("./images/1.jpg", img_url)

2.4 完整脚本

import requests
import re
import timeurl = "http://192.168.188.187/pythonSpider/"headers = {"User-Agent":   "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36"
}# 定义了一个名为get_html的函数,用于发送HTTP GET请求获取指定URL的响应内容,并返回其二进制形式的内容。
def get_html(url):res = requests.get(url = url, headers = headers)return res.content# 接受一个字符串类型的HTML内容作为参数,并使用正则表达式 re.findall() 来提取页面源代码中的图片路径,然后将其以列表形式返回。
def get_img_path_list(html):img_path_list = re.findall(r"style/\w*\.jpg", html)return img_path_list# 接受两个参数 img_save_path 和 img_url,函数内部使用二进制写入模式打开指定的本地文件路径 img_save_path,然后将通过调用 get_html 函数获取到的图片内容写入该文件。
def img_download(img_save_path, img_url):with open(img_save_path, "wb") as f:f.write(get_html(url = img_url))# 调用 get_html 函数,传入 url 参数,发送HTTP请求并获取网页响应的内容,然后使用 .decode() 方法将其解码为字符串形式。        
html = get_html(url = url).decode()# 调用 get_img_path_list 函数,传入 html 参数,该参数是上一步获取到的网页内容,函数将返回一个包含图片路径的列表。
img_path_list = get_img_path_list(html = html)for img_path in img_path_list:# 对于每个图片路径 img_path,拼接出完整的图片链接 img_urlimg_url = url + img_path# 使用当前时间戳构造出本地保存路径 img_save_pathimg_save_path = f"./images/{time.time()}.jpg"# 传入图片保存路径和图片链接进行下载。img_download(img_save_path = img_save_path, img_url = img_url)

3. requests 模块基本用法

3.1 获取浏览器指纹

import requestsurl = "http://192.168.188.187/pythonSpider/index.html"headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0"
}# 默认同一个会话脚本中的请求可能有多个,requests.Session可以维护持久化的连接和会话状态
req = requests.Session()    # 保持一致性# 调用 requests 库的 get() 方法,传入 url 和 headers 参数,发送HTTP GET请求,并将返回的响应对象赋值给变量 res。
res = req.get(url = url , headers = headers)# print(res.text)            # 响应正文内容的字符串
print("====================================")
print(res.status_code)       # 打印响应状态码
print("====================================")
print(res.headers)           # 打印响应头信息
print("====================================")
print(res.url)               # 请求的URL的地址
print("====================================")
print(res.encoding)          # 显示页面的编码
print("====================================")
print(res.request.headers)   # 打印request属性的headers字段

3.2 发送GET 参数

import requestsurl = "http://192.168.188.187/pythonSpider/index.html"headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0"
}# 默认同一个会话脚本中的请求可能有多个,requests.Session可以维护持久化的连接和会话状态
req = requests.Session()    # 保持一致性params = {"username" : "WUHU","password" : "123456"
}# 调用 requests 库的 get() 方法,传入 url、headers 和 params 参数,发送HTTP GET请求,并将返回的响应对象赋值给变量 res。在这个例子中,params 参数会被自动构造成查询字符串并附加在URL后面。
res = req.get(url = url , headers = headers, params = params)print(res.url)

3.3 发送POST 参数

import requestsurl = "http://192.168.188.187/pythonSpider/index.html"headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0"
}# 默认同一个会话脚本中的请求可能有多个,requests.Session可以维护持久化的连接和会话状态
req = requests.Session()    # 保持一致性# 设置请求的表单数据,这里使用字典表示用户名和密码。
data = {"username" : "WUHU","password" : "123456"
}# 使用Session对象的post方法发送POST请求。传入URL、请求头和表单数据作为参数。请求头和表单数据将被添加到HTTP请求中。
res = req.post(url = url , headers = headers, data = data)print(res.url)
print(res.request.body)

3.4 文件上传

模拟文件上传,以DVWA靶场中的文件上传漏洞Low级别为例

image-20230920190805663

使用bp抓取数据包查看需要哪些参数

image-20230920191010573

脚本内容如下:

import requests
import re
import bs4url = "http://192.168.188.187/dvwa_2.0.1/vulnerabilities/upload/"req = requests.Session()# 还得携带Cookie信息,因为在上传文件的时候,只有登录成功后才可以进行上传文件。
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36","Cookie": "security=low; security=low; PHPSESSID=jvrc2c84pq9dnvdcqvd545t4o1"
}# 添加变量MAX_FILE_SIZE,Upload
data= {"MAX_FILE_SIZE" : "100000","Upload" : "Upload"
}# 字典的key就是文件域的名字
# value包含文件名,文件类型,文件内容。以元组的显示表现,因为文件的信息不可以修改
# 文件内容前面添加一个b表示二进制数据
# 注意顺序是文件名,文件内容,文件类型
files= {"uploaded" : ("wuhu.php", b"<?php phpinfo();?>", "image/png")
}res= req.post(url= url, headers= headers, data= data, files= files)# print(res.text)# 正则匹配
# file_path = re.findall(r"<pre>(.*) succesfully uploaded!</pre>", res.content.decode())[0]
# print(file_path)# 在文档中解析pre标签
html = res.text
html = bs4.BeautifulSoup(html,"lxml")   # 解析为lxml格式# 搜索pre标签
pre = html.find_all("pre")# 从标签中获取文本
pre = pre[0].text# 对字符串进行切片
file_path = pre[0:pre.find(" ")]# 字符串拼接
file_path = url + file_pathprint(file_path)

脚本执行结果

image-20230920191625666

页面访问效果

image-20230920193058203

3.4.1 注意事项
  • files字典的key就是文件域的名字

image-20230920173329167

  • 文件内容前面添加一个 b 表示二进制数据。

image-20230920175601605

  • 需要添加两个信息分别是:MAX_FILE_SIZE,Upload

image-20230920174143417

  • 还得携带Cookie信息,因为在上传文件的时候,只有登录成功后才可以进行上传文件。

image-20230920175547033

  • files字典的顺序是文件名,文件内容,文件类型

image-20230920191438031

  • 在提取文件的上传路径时候可以采用正则匹配也可以使用Python中的第三方库 BeautifulSoup

BeautifulSoup 是一个用于解析 HTML 和 XML 文档的库,它提供了方便的方法和工具来从网页中提取数据。通过使用 BeautifulSoup,可以轻松地遍历、搜索和操作 HTML/XML 树结构,从而实现对网页内容的抽取和分析。

3.5 服务器超时

说明:服务器超时脚本可以编写SQL注入中的延时注入脚本。

sleep.php文件

<?phpsleep(8);echo "wuhu haha heihei";
?>

服务器超时脚本

# 09 - 服务器超时.py
import requestsurl = "http://192.168.188.187/php/functions/sleep.php"headers= {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36"
}def get_timeout(url):try:req =  requests.Session()# timeout = 5表示在5秒之内没有等到服务器的回应就不等了res = req.get(url= url , headers = headers, timeout = 5)except:return "timeout!"else:return res.textprint(get_timeout(url))

如果sleep.php中延时8秒那么服务器超时脚本就会输出"timeout!"。

image-20230920190515840

延时3秒服务输出"wuhu haha heihei"。

image-20230920190451041

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

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

相关文章

服务器端应用的安装

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

机器学习第九课--随机森林

一.什么是集成模型 对于几乎所有的分类问题(图像识别除外&#xff0c;因为对于图像识别问题&#xff0c;目前深度学习是标配)&#xff0c;集成模型很多时候是我们的首选。比如构建一个评分卡系统&#xff0c;业界的标配是GBDT或者XGBoost等集成模型&#xff0c;主要因为它的效…

Windows/Linux(命令、安装包和源码安装)平台各个版本QT详细安装教程

前言 本文章主要介绍了Windows/Linux平台下&#xff0c;QT4&#xff0c;QT5&#xff0c;QT6的安装步骤。为什么要把QT版本分开介绍呢&#xff0c;因为这三个版本&#xff0c;安装步骤都不一样。Windows平台&#xff0c;QT4的Qt Creator&#xff0c;QT库和编译器是分开的&#…

Postman应用——Collection、Folder和Request

文章目录 Collection新建CollectionCollection重命名保存Request到Collection在Collection下创建Request删除Collection Folder新建FolderFolder重命名保存Request到Folder在Folder下创建Request在Folder下创建Folder删除Folder Request创建临时RequestRequest重命名删除Reques…

攻防世界-WEB-fileinclude

访问url&#xff0c;可以看到一些提示&#xff0c;绝对路径/var/www/html/index.php&#xff0c;也提示了flag在flag.php中。 快捷键Ctrlu,查看网页源代码 思路&#xff1a; 源代码中看到 include($lan.".php"); &#xff0c;可知此处存在文件包含。$lan的值是从co…

QGIS怎么修改源代码?持续更新...

修改配置文件保存位置 修改目的&#xff1a;放着和本地安装的其他QGIS共用一份配置文件 修改文件&#xff1a;core/qgsuserprofilemanager.cpp 修改位置&#xff1a;第37行 return basePath QDir::separator() "my_profiles";修改完毕后&#xff0c;再次生成一下…

计算机和编程语言初见

学习程序设计的目的是什么呢&#xff1f; 不一定要做出一个软件或系统出来&#xff0c;更重要的是理解计算机是如何工作的以及它的长处和短处。 计算机本身是无意识的&#xff0c;因此我们要求它为我们做事时&#xff1a;应该将步骤细化、“直”化&#xff08;规律化&#xf…

day51: QTday4,绘制事件、QT连接TCP网络通信

一、绘制时钟 widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QRectF> #include <QTimer> #include <QTime> #include <QTimerEvent> #include <QLabe…

Spring Authorization Server入门 (十八) Vue项目使用PKCE模式对接认证服务

Vue单页面项目使用授权码模式对接流程说明 以下流程摘抄自官网 在本例中为授权代码流程。 授权码流程的步骤如下&#xff1a; 客户端通过重定向到授权端点来发起 OAuth2 请求。 对于公共客户端&#xff0c;此步骤包括生成code_verifier 并计算code_challenge&#xff0c;然后…

mysql数据库备份(mysqldump)

mysqldump命令备份数据 mysqldump -u root -p --databases 数据库1 数据库2 > xxx.sqlmysqldump常用操作示例 1. 备份全部数据库的数据和结构 mysqldump -uroot -p123456 -A > /data/mysqlbackup/mydb.sql2. 备份全部数据库的结构&#xff08;加 -d 参数&#xff09; …

【音视频】ffplay解析-音视频同步

音视频同步 主要解析&#xff1a;以音频为基准&#xff0c;让视频合成音频 思路 视频慢了则丢掉部分视频帧&#xff08;视觉->画⾯跳帧&#xff09; 视频快了则继续渲染上⼀帧 具体实现 一个国际标准&#xff1a;音频帧-视频帧时间戳的差值在-100ms~25ms内流畅 1.差值音频…

菜鸟教程《Python 3 教程》笔记(20):面向对象

菜鸟教程《Python 3 教程》笔记&#xff08;20&#xff09; 20 面向对象20.1 面向对象技术简介20.2 创建类20.2.1 类定义20.2.2 实例化20.2.3 初始化20.2.4 类变量、实例变量20.2.5 类方法、实例方法、静态方法 20.3 访问可见性20.3.1 property装饰器 20.4 动态性20.4.1 __slot…

wpf资源Resources探究性学习(一)

测试环境&#xff1a; vistual studio 2017 .net framework 3.5 window 10 新建WPF应用(.net framework)&#xff0c;项目名称为&#xff1a;WpfDemo&#xff0c;如下图&#xff1a; 新建完项目后&#xff0c;默认带有一个名为MainWindow.xaml的代码 一 简单使用字符串资源…

js常用的数组处理方法

some 方法 用于检查数组中是否至少有一个元素满足指定条件。如果有满足条件的元素&#xff0c;返回值为 true&#xff0c;否则返回 false。 const numbers [1, 2, 3, 4, 5];const hasEvenNumber numbers.some((number) > number % 2 0); console.log(hasEvenNumber); /…

1_图神经网络GNN基础知识学习

文章目录 安装PyTorch Geometric安装工具包 在KarateClub数据集上使用图卷积网络 (GCN) 进行节点分类两个画图函数Graph Neural Networks数据集&#xff1a;Zacharys karate club network.PyTorch Geometric数据集介绍 edge_index使用networkx可视化展示 Graph Neural Networks…

H3C 6520X版本U盘升级

1.软件下载链接&#xff1a; 核心交换机-以太网交换机-工业交换机-新华三集团-H3C 账号&#xff1a;yx800 密码&#xff1a;01230123 2.将升级包放进U盘 3.登录交换机&#xff0c;给交换机插上U盘 >copy usba0:/S6520X-CMW710-R6628P40.ipe S6520X-CMW710-R6628P40.ip…

(并查集) 1971. 寻找图中是否存在路径 ——【Leetcode每日一题】

❓ 1971. 寻找图中是否存在路径 难度&#xff1a;简单 有一个具有 n 个顶点的 双向 图&#xff0c;其中每个顶点标记从 0 到 n - 1&#xff08;包含 0 和 n - 1&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 …

Flash的学习

Flash的学习 1 概述 2 特性 STM32 的内部FLASH 包含主存储器、系统存储器以及选项字节区域。 2.1 主存储器 主存储器分为256 页&#xff0c;每页大小为2KB&#xff0c;共512KB。这个分页的概念&#xff0c;实质就是FLASH 存储器 的扇区&#xff0c;与其它FLASH 一样&…

UWB定位模块

UWB定位模组是华星智控自研的小尺寸高集成度模组&#xff0c;模组长宽厚为30.1513.955.62毫米&#xff0c;天线采用IPEX接口分体式设计&#xff0c;方便集成于您的产品中&#xff0c;产品采用本安设计&#xff0c;可以用于煤矿等井下场景&#xff0c;通信距离>100米&#xf…

统计十进制数的二进制表示中1的个数 ← 清华 邓俊辉

【题目描述】 统计十进制数的二进制表示中1的个数。【算法分析】 虽然曾在 https://blog.csdn.net/hnjzsyjyj/article/details/110148954 发过一篇关于“统计十进制数的二进制表示中1的个数”的博客&#xff0c;但本文实现了一种新的思路。此思路来源于清华大学邓俊辉版《数据结…