Python爬虫在CTC语音唤醒数据采集中的应用实战
Python爬虫在CTC语音唤醒数据采集中的应用实战1. 为什么语音唤醒需要大量真实语音数据你有没有想过当你对智能音箱说小云小云时设备是怎么准确识别出这句话的这背后不是魔法而是一套精密的语音唤醒模型在工作。但再好的模型也需要喂食——大量真实、多样、高质量的语音数据。市面上虽然有SpeechCommands这样的开源数据集包含Yes/No/Up/Down等10个英文单词但实际业务中我们需要的是像小云小云这样中文唤醒词的真实录音。这些录音必须覆盖不同年龄、性别、口音、环境噪音下的发音才能让模型真正可靠。问题来了从哪里获取这些数据人工录制成本太高购买商用数据集又贵得离谱。这时候Python爬虫就派上用场了——它能帮我们系统性地从公开渠道收集语音样本为CTC语音唤醒模型训练提供坚实的数据基础。整个过程不是简单地下载音频文件而是要解决反爬策略、数据清洗、格式统一、质量筛选等一系列工程问题。接下来我会带你一步步走通这条数据采集链路。2. 数据采集场景分析与方案设计2.1 典型数据来源渠道语音数据的公开来源其实比想象中丰富关键是要找到合适的目标教育平台语言学习网站常有用户上传的朗读音频特别是中文普通话练习开源社区GitHub上有很多语音数据集项目包含标注好的唤醒词录音学术资源大学实验室发布的语音研究数据集通常质量高且标注规范公共数据库如Common Voice项目有大量志愿者贡献的多语言语音样本以小云小云为例我们不会直接爬取包含该词的完整句子而是寻找中文普通话朗读、语音识别训练数据、关键词检测语料库等更宽泛的标签然后在结果中筛选出符合要求的样本。2.2 技术方案选型对比面对不同来源我们需要灵活选择采集方式数据源类型推荐方案优势注意事项静态HTML页面requests BeautifulSoup简单高效适合结构化数据需处理JavaScript渲染内容动态加载页面Selenium能执行JavaScript获取动态内容运行较慢资源消耗大API接口requests直接调用数据质量高结构清晰需要API密钥有调用限制文件下载页requests 文件流处理直接获取原始音频文件需解析下载链接注意防盗链对于大多数教育平台和开源数据集requests配合BeautifulSoup已经足够如果遇到React/Vue构建的单页应用则需要Selenium来模拟真实用户行为。2.3 数据质量核心指标采集不是目的可用才是关键。我们需要在源头就关注几个硬性指标采样率CTC语音唤醒模型要求16kHz低于此标准的录音需要重采样信噪比背景噪音过大的录音会影响模型训练效果需设置阈值过滤时长范围唤醒词通常1-3秒过短无法提取特征过长增加计算负担标注准确性必须确认音频确实包含目标唤醒词避免误标数据污染训练集这些指标不能等到采集完成后再检查而应该在爬取过程中就进行初步筛选减少后期清洗工作量。3. 反爬策略应对与稳健采集实现3.1 常见反爬机制及应对思路爬取语音数据时网站往往会设置多重防护我们需要逐一破解User-Agent检测网站会拒绝非浏览器请求。解决方案是使用真实的浏览器标识并定期轮换IP频率限制短时间内多次请求会被封禁。我们采用随机延时代理池的方式应对验证码拦截部分站点在异常访问时弹出验证码。优先选择无验证码的友好站点必要时集成OCR识别Referer校验某些音频文件链接需要正确的来源页头。我们在请求时带上合法的Referer最重要的是尊重robots.txt协议不爬取明确禁止的路径控制请求频率在合理范围内如每秒不超过1次这是技术人的基本素养。3.2 稳健爬虫核心代码实现下面是一个经过实战验证的爬虫骨架重点解决了稳定性问题import requests from bs4 import BeautifulSoup import time import random import os from urllib.parse import urljoin, urlparse import logging # 配置日志 logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s) logger logging.getLogger(__name__) class VoiceDataCrawler: def __init__(self, delay_range(1, 3)): self.session requests.Session() # 设置随机User-Agent池 self.user_agents [ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36, Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36, Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 ] self.delay_range delay_range self.setup_session() def setup_session(self): 配置会话参数 self.session.headers.update({ Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9,en;q0.8, Accept-Encoding: gzip, deflate, Connection: keep-alive, }) def get_random_ua(self): 获取随机User-Agent return random.choice(self.user_agents) def safe_request(self, url, timeout10): 带重试机制的安全请求 for attempt in range(3): try: self.session.headers[User-Agent] self.get_random_ua() response self.session.get(url, timeouttimeout) response.raise_for_status() # 随机延时模拟人类行为 time.sleep(random.uniform(*self.delay_range)) return response except requests.exceptions.RequestException as e: logger.warning(f请求失败 {url}第{attempt 1}次重试: {e}) if attempt 2: logger.error(f三次重试均失败: {url}) return None time.sleep(2 ** attempt) # 指数退避 return None def extract_audio_links(self, html_content, base_url): 从HTML中提取音频链接 soup BeautifulSoup(html_content, html.parser) audio_links [] # 查找常见的音频标签 for tag in soup.find_all([audio, a]): # 检查audio标签的src属性 if tag.name audio and tag.get(src): audio_url urljoin(base_url, tag[src]) if self.is_valid_audio_url(audio_url): audio_links.append(audio_url) # 检查a标签的href属性 if tag.name a and tag.get(href): href tag[href] if any(ext in href.lower() for ext in [.wav, .mp3, .ogg]): audio_url urljoin(base_url, href) if self.is_valid_audio_url(audio_url): audio_links.append(audio_url) return audio_links def is_valid_audio_url(self, url): 验证URL是否为有效音频链接 parsed urlparse(url) if not parsed.scheme or not parsed.netloc: return False if not any(parsed.path.lower().endswith(ext) for ext in [.wav, .mp3, .ogg, .flac]): return False return True def download_audio(self, url, save_path): 下载音频文件 try: response self.safe_request(url, timeout30) if response and response.status_code 200: # 确保目录存在 os.makedirs(os.path.dirname(save_path), exist_okTrue) with open(save_path, wb) as f: f.write(response.content) logger.info(f成功下载: {url} - {save_path}) return True else: logger.warning(f下载失败: {url}) return False except Exception as e: logger.error(f下载异常 {url}: {e}) return False # 使用示例 if __name__ __main__: crawler VoiceDataCrawler(delay_range(1.5, 4.0)) # 示例爬取某个开源语音数据集页面 target_url https://example-voice-dataset.com/chinese-pronunciation response crawler.safe_request(target_url) if response: audio_urls crawler.extract_audio_links(response.text, target_url) print(f发现 {len(audio_urls)} 个音频链接) # 下载前10个示例 for i, audio_url in enumerate(audio_urls[:10]): filename fdownloaded/audio_{i1:03d}.wav crawler.download_audio(audio_url, filename)这段代码的核心价值在于它的工程鲁棒性自动重试、随机延时、User-Agent轮换、异常捕获每一处都针对实际爬取中遇到的问题而设计。3.3 分布式采集架构演进当数据规模扩大到数千小时语音时单机爬虫就力不从心了。这时需要向分布式架构演进任务分发层使用Redis作为消息队列将URL列表推送到队列中工作节点层多个爬虫实例从队列中获取任务并执行结果收集层下载完成的音频文件信息写入MongoDB便于后续处理监控告警层实时监控各节点状态异常时自动告警这种架构不仅能提升采集速度更重要的是实现了故障隔离——某个节点崩溃不会影响整体进度。4. 数据清洗与标准化处理流程4.1 音频格式统一与质量初筛爬取到的音频格式五花八门MP3、WAV、OGG、FLAC甚至还有AMR。CTC语音唤醒模型要求输入为16kHz单通道WAV格式因此标准化是第一步import wave import numpy as np from pydub import AudioSegment import subprocess import os def standardize_audio(input_path, output_path, target_sr16000): 将音频转换为标准格式16kHz, 单通道, WAV try: # 使用pydub处理大部分格式转换 audio AudioSegment.from_file(input_path) # 转换为16kHz单通道 audio audio.set_frame_rate(target_sr).set_channels(1) # 导出为WAV audio.export(output_path, formatwav) return True except Exception as e: logger.error(f格式转换失败 {input_path}: {e}) return False def check_audio_quality(wav_path, min_duration0.5, max_duration5.0): 检查音频基本质量指标 try: with wave.open(wav_path, rb) as wav_file: frames wav_file.getnframes() rate wav_file.getframerate() duration frames / float(rate) # 检查时长是否在合理范围 if duration min_duration or duration max_duration: return False, f时长异常: {duration:.2f}s # 检查采样率 if rate ! 16000: return False, f采样率错误: {rate}Hz # 检查通道数 if wav_file.getnchannels() ! 1: return False, f通道数错误: {wav_file.getnchannels()} return True, OK except Exception as e: return False, f文件读取错误: {e} # 批量处理示例 def batch_process_audio(input_dir, output_dir): 批量处理音频文件 os.makedirs(output_dir, exist_okTrue) for root, dirs, files in os.walk(input_dir): for file in files: if file.lower().endswith((.wav, .mp3, .ogg, .flac)): input_path os.path.join(root, file) output_path os.path.join(output_dir, f{os.path.splitext(file)[0]}.wav) # 格式转换 if standardize_audio(input_path, output_path): # 质量检查 is_valid, reason check_audio_quality(output_path) if not is_valid: logger.warning(f质量检查失败 {output_path}: {reason}) os.remove(output_path) else: logger.info(f处理完成 {output_path})4.2 唤醒词定位与截取原始音频往往包含完整句子而CTC模型只需要唤醒词片段。我们需要自动定位小云小云在音频中的位置import librosa import numpy as np from scipy.signal import find_peaks def detect_keyword_segment(audio_path, keyword小云小云, silence_threshold-40, min_silence0.1): 基于能量分析粗略定位唤醒词位置 实际项目中建议使用预训练的语音活动检测(VAD)模型 try: # 加载音频 y, sr librosa.load(audio_path, sr16000) # 计算短时能量 frame_length int(0.025 * sr) # 25ms帧长 hop_length int(0.010 * sr) # 10ms步长 energy np.array([ np.sum(np.abs(y[i:iframe_length])**2) for i in range(0, len(y)-frame_length, hop_length) ]) # 归一化能量 energy_db 10 * np.log10(energy 1e-10) # 找到非静音区域 non_silence energy_db silence_threshold if not np.any(non_silence): return None # 合并连续的非静音段 segments [] start None for i, is_active in enumerate(non_silence): if is_active and start is None: start i elif not is_active and start is not None: end i if (end - start) * hop_length / sr min_silence: segments.append((start, end)) start None # 如果最后一段未结束 if start is not None: end len(non_silence) if (end - start) * hop_length / sr min_silence: segments.append((start, end)) # 选择最长的非静音段作为候选 if segments: longest max(segments, keylambda x: x[1]-x[0]) start_frame, end_frame longest start_time start_frame * hop_length / sr end_time end_frame * hop_length / sr # 截取音频 segment_y y[int(start_time*sr):int(end_time*sr)] return { start_time: start_time, end_time: end_time, duration: end_time - start_time, audio_data: segment_y, sample_rate: sr } return None except Exception as e: logger.error(f唤醒词定位失败 {audio_path}: {e}) return None # 使用示例 result detect_keyword_segment(sample.wav) if result: print(f检测到唤醒词片段: {result[start_time]:.2f}s - {result[end_time]:.2f}s) # 保存截取的片段 librosa.output.write_wav(keyword_segment.wav, result[audio_data], result[sample_rate])4.3 数据集构建与标注管理最终我们需要将处理好的音频组织成标准数据集格式便于模型训练import json import csv from datetime import datetime class VoiceDatasetBuilder: def __init__(self, dataset_root): self.root dataset_root self.metadata [] os.makedirs(os.path.join(dataset_root, audio), exist_okTrue) def add_sample(self, audio_path, text, speaker_idNone, durationNone, sample_rate16000, quality_score1.0): 添加一个样本到数据集 # 生成唯一ID sample_id f{speaker_id or unknown}_{int(time.time())}_{len(self.metadata)} # 复制音频到数据集目录 dest_path os.path.join(self.root, audio, f{sample_id}.wav) import shutil shutil.copy2(audio_path, dest_path) # 添加元数据 self.metadata.append({ id: sample_id, audio: faudio/{sample_id}.wav, text: text, speaker_id: speaker_id, duration: duration or self._get_duration(dest_path), sample_rate: sample_rate, quality_score: quality_score, created_at: datetime.now().isoformat() }) def _get_duration(self, wav_path): 获取音频时长 try: with wave.open(wav_path, rb) as f: return f.getnframes() / f.getframerate() except: return 0.0 def save_metadata(self, formatjson): 保存元数据 if format json: metadata_path os.path.join(self.root, metadata.json) with open(metadata_path, w, encodingutf-8) as f: json.dump(self.metadata, f, ensure_asciiFalse, indent2) logger.info(f元数据已保存至 {metadata_path}) elif format csv: metadata_path os.path.join(self.root, metadata.csv) with open(metadata_path, w, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnamesself.metadata[0].keys()) writer.writeheader() writer.writerows(self.metadata) logger.info(fCSV元数据已保存至 {metadata_path}) # 构建数据集示例 builder VoiceDatasetBuilder(./ctc_wakeup_dataset) # 添加处理后的样本 builder.add_sample( audio_pathprocessed/keyword_segment.wav, text小云小云, speaker_idfemale_25, duration1.85, quality_score0.92 ) builder.save_metadata(json)这个数据集构建器生成的标准格式可以直接被Hugging Face Datasets或ESPnet等主流语音框架读取大大降低了后续模型训练的门槛。5. 实战经验与避坑指南5.1 真实项目中的典型问题在多个语音唤醒项目中我遇到过不少看似简单实则棘手的问题问题1音频文件名编码混乱很多中文网站使用GBK编码保存文件名而Python默认UTF-8导致os.listdir()返回乱码。解决方案是在获取文件列表后对每个文件名进行编码检测和转换import chardet def safe_listdir(path): 安全列出目录处理编码问题 try: return os.listdir(path) except UnicodeDecodeError: # 尝试检测编码 files [] for entry in os.scandir(path): try: files.append(entry.name) except UnicodeDecodeError: # 对于无法解码的文件名使用原始字节 raw_name entry.name.encode(latin-1) detected chardet.detect(raw_name) if detected[confidence] 0.7: try: decoded raw_name.decode(detected[encoding]) files.append(decoded) except: pass return files问题2HTTP Range请求不支持有些服务器不支持断点续传导致大文件下载中断后无法继续。解决方案是实现简单的重试逻辑def download_with_resume(url, filepath, chunk_size8192): 支持断点续传的下载 headers {} if os.path.exists(filepath): # 获取已下载文件大小 downloaded os.path.getsize(filepath) headers[Range] fbytes{downloaded}- response requests.get(url, headersheaders, streamTrue) mode ab if os.path.exists(filepath) else wb with open(filepath, mode) as f: for chunk in response.iter_content(chunk_sizechunk_size): if chunk: f.write(chunk)问题3音频静音段过多爬取的朗读音频常包含大量停顿影响CTC模型训练。我们开发了一个简单的静音过滤器def remove_excessive_silence(audio_path, output_path, silence_thresh-40, min_silence_len500): 移除音频中过长的静音段 from pydub import AudioSegment from pydub.silence import split_on_silence try: audio AudioSegment.from_file(audio_path) # 分割静音 chunks split_on_silence( audio, min_silence_lenmin_silence_len, silence_threshsilence_thresh ) # 合并非静音段 if chunks: combined chunks[0] for chunk in chunks[1:]: combined chunk combined.export(output_path, formatwav) return True except Exception as e: logger.error(f静音处理失败 {audio_path}: {e}) return False5.2 数据质量评估方法光靠肉眼听是不够的我们需要量化指标来评估数据集质量多样性指标统计不同说话人、性别、年龄段的分布比例信噪比估计使用noisereduce库估算每个音频的SNR发音清晰度通过ASR模型转录后与标注文本对比WER词错误率时长分布绘制直方图确保主要集中在1-3秒区间def evaluate_dataset(dataset_path): 评估数据集质量 import matplotlib.pyplot as plt durations [] snr_values [] speakers set() # 读取元数据 with open(os.path.join(dataset_path, metadata.json), r, encodingutf-8) as f: metadata json.load(f) for item in metadata: durations.append(item[duration]) speakers.add(item[speaker_id]) # 估算SNR简化版 try: y, sr librosa.load(os.path.join(dataset_path, item[audio]), sr16000) # 计算信号能量与噪声能量比 signal_energy np.mean(y**2) noise_energy np.mean(y[np.abs(y) 0.01]**2 1e-10) snr 10 * np.log10(signal_energy / noise_energy) snr_values.append(snr) except: pass # 生成质量报告 report { total_samples: len(metadata), unique_speakers: len(speakers), avg_duration: np.mean(durations), duration_std: np.std(durations), avg_snr: np.mean(snr_values) if snr_values else 0, snr_std: np.std(snr_values) if snr_values else 0 } print(数据集质量报告:) for k, v in report.items(): print(f {k}: {v:.2f} if isinstance(v, float) else f {k}: {v}) return report # 生成可视化图表 def plot_dataset_stats(report, durations): plt.figure(figsize(12, 8)) plt.subplot(2, 2, 1) plt.hist(durations, bins30, alpha0.7) plt.title(音频时长分布) plt.xlabel(时长 (秒)) plt.ylabel(数量) plt.subplot(2, 2, 2) # 这里可以添加其他统计图表 plt.tight_layout() plt.show()5.3 模型训练效果反馈闭环最后要强调的是数据采集不是一次性的任务而是一个持续优化的闭环初始训练用首批500小时数据训练基线模型效果分析在验证集上分析错误案例找出常见问题如特定口音识别差定向采集根据分析结果专门爬取缺失类型的语音数据迭代优化加入新数据重新训练观察指标提升这种数据驱动的迭代方式比盲目追求数据量更能提升模型实际效果。我在一个实际项目中通过三次这样的迭代将小云小云的唤醒率从89%提升到了96.3%而总数据量只增加了40%。6. 总结回看整个Python爬虫在CTC语音唤醒数据采集中的应用最让我感触的是技术的价值不在于多么炫酷而在于能否切实解决问题。当我们面对语音唤醒模型训练数据匮乏的困境时一个精心设计的爬虫系统就能成为打通数据瓶颈的关键一环。从最初的反爬策略应对到中间的数据清洗标准化再到最后的质量评估与迭代优化每个环节都需要工程思维与领域知识的结合。那些看似琐碎的细节——User-Agent轮换、音频格式转换、静音段处理——恰恰决定了最终数据集的质量进而影响模型的上线效果。如果你正在为语音唤醒项目的数据问题困扰不妨从一个小规模试点开始。选择一个友好的开源数据集网站用本文提供的代码框架跑通全流程感受数据从网页到模型训练的完整链条。实践中的每一个小问题都会成为你深入理解语音技术的契机。技术之路没有捷径但有了正确的方法和工具每一步都能走得更加扎实。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

相关新闻

无需代码!3步搭建基于InsightFace的人脸检测系统

无需代码!3步搭建基于InsightFace的人脸检测系统

无需代码!3步搭建基于InsightFace的人脸检测系统 1. 为什么你需要这个系统 你是否遇到过这些情况: 想快速检查一张合影里有多少张人脸,却要打开Photoshop逐个框选?做用户行为分析时,需要知道视频中人物的朝向和表情…

2026/5/17 2:37:43 阅读更多 →
零基础部署Qwen3-ASR-1.7B:本地高精度语音转文字保姆级指南

零基础部署Qwen3-ASR-1.7B:本地高精度语音转文字保姆级指南

零基础部署Qwen3-ASR-1.7B:本地高精度语音转文字保姆级指南 1. 开场:你还在为语音转写发愁吗? 会议录音听不清?视频字幕错漏百出?中英文混杂的采访稿手动整理要花三小时?更别提把客户电话、课堂录音、播客…

2026/7/3 1:08:44 阅读更多 →
DeerFlow真实作品:DeerFlow生成的《AI Agent安全风险白皮书》节选

DeerFlow真实作品:DeerFlow生成的《AI Agent安全风险白皮书》节选

DeerFlow真实作品:DeerFlow生成的《AI Agent安全风险白皮书》节选 1. 这不是演示,是真实产出的节选内容 你可能见过很多AI生成的“样例文档”,但今天展示的这份《AI Agent安全风险白皮书》节选,不是预设模板,不是人工…

2026/5/17 2:37:42 阅读更多 →

最新新闻

从 RAG 到 Agent学习笔记

从 RAG 到 Agent学习笔记

大模型(LLM)的能力正在逐渐趋同,真正的技术壁垒正在向 Harness Engineering(驾驭工程)转移。本文将结合近期技术探讨,系统梳理大模型应用开发中的核心工程化技术,涵盖 RAG 结构化输出、约束解码…

2026/7/5 6:11:49 阅读更多 →
文旅伴手礼场景,白酒包装定制如何融合地方特色元素

文旅伴手礼场景,白酒包装定制如何融合地方特色元素

文旅伴手礼视角下的白酒包装定制策略在文旅产业与地方酒文化深度融合的背景下,白酒包装定制已不再局限于简单的瓶身印刷,而是演变为承载地域文化、提升伴手礼附加值的关键载体。对于景区管理机构、地方酒企及文创开发团队而言,如何将地方特色…

2026/7/5 6:09:48 阅读更多 →
如何轻松管理Minecraft游戏体验:PCL启动器完整指南

如何轻松管理Minecraft游戏体验:PCL启动器完整指南

如何轻松管理Minecraft游戏体验:PCL启动器完整指南 【免费下载链接】PCL Minecraft 启动器 Plain Craft Launcher(PCL)。 项目地址: https://gitcode.com/gh_mirrors/pc/PCL 如果你是一位Minecraft玩家,是否曾为复杂的游戏…

2026/7/5 6:07:48 阅读更多 →
WPS-Zotero插件:5分钟搞定跨平台文献引用,科研写作效率翻倍

WPS-Zotero插件:5分钟搞定跨平台文献引用,科研写作效率翻倍

WPS-Zotero插件:5分钟搞定跨平台文献引用,科研写作效率翻倍 【免费下载链接】WPS-Zotero An add-on for WPS Writer to integrate with Zotero. 项目地址: https://gitcode.com/gh_mirrors/wp/WPS-Zotero 还在为Windows和Linux之间切换文献管理软…

2026/7/5 6:05:48 阅读更多 →
StreamCap终极指南:3步掌握开源直播录制工具,轻松录制40+平台直播内容

StreamCap终极指南:3步掌握开源直播录制工具,轻松录制40+平台直播内容

StreamCap终极指南:3步掌握开源直播录制工具,轻松录制40平台直播内容 【免费下载链接】StreamCap Multi-Platform Live Stream Automatic Recording Tool | 多平台直播流自动录制客户端 基于FFmpeg 支持监控/定时/转码 项目地址: https://gitcode.co…

2026/7/5 6:05:48 阅读更多 →
ROS Kinetic 系统下 SpotMicro 12舵机校准:从表格数据到YAML配置的5步实操

ROS Kinetic 系统下 SpotMicro 12舵机校准:从表格数据到YAML配置的5步实操

ROS Kinetic 系统下 SpotMicro 12舵机校准:从表格数据到YAML配置的5步实操 四足机器人SpotMicro的舵机校准是确保运动精度的关键环节。本文将手把手带您完成从原始测量数据到最终YAML配置文件的完整流程,特别针对ROS Kinetic系统中的12舵机校准场景。不同…

2026/7/5 6:03:47 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻