Qwen3-ASR-1.7B语音识别实战:基于Python爬虫的音频数据采集与处理
Qwen3-ASR-1.7B语音识别实战:基于Python爬虫的音频数据采集与处理
最近在做一个语音分析的项目,需要处理大量来自网络的音频数据。手动下载、转格式、再识别,这个流程想想就头大。后来发现,把Python爬虫和Qwen3-ASR-1.7B这个语音识别模型结合起来,能实现一条龙的自动化处理,效率提升不是一点半点。
如果你也遇到过类似情况,比如想分析播客内容、整理会议录音,或者做语音数据的研究,这套方法应该能帮上忙。它核心就三步:用爬虫把网上的音频文件抓下来,统一转换成模型能吃的格式,最后批量扔给模型去识别成文字。整个过程写个脚本就能跑起来,特别适合处理成百上千个文件。
接下来,我就带你走一遍这个实战流程,从环境搭建到最终出结果,保证你能跟着做出来。
1. 项目准备与环境搭建
工欲善其事,必先利其器。咱们先把需要的工具和库准备好。
1.1 核心工具选择
这个项目主要用到两类工具:
- 数据采集端:Python爬虫。我们选择
requests库来下载文件,用BeautifulSoup来解析网页,找到音频文件的链接。这两个库用起来简单直接,社区资源也丰富。 - 语音识别端:Qwen3-ASR-1.7B模型。这是一个专门为中文场景优化的自动语音识别模型,体积相对小巧(1.7B参数),在保证不错识别率的同时,对硬件要求比较友好,个人电脑也能跑起来。我们将通过
transformers库来调用它。
1.2 一步步安装依赖
打开你的终端或命令行,创建一个新的项目目录,然后安装必要的Python包。建议先创建一个虚拟环境,避免包版本冲突。
# 创建并激活虚拟环境(以conda为例,你也可以用venv)
conda create -n asr_spider python=3.9
conda activate asr_spider
# 安装核心依赖
pip install requests beautifulsoup4 transformers torch
# 如果需要处理更多音频格式,可以安装ffmpeg和pydub
# 首先确保系统安装了ffmpeg(Ubuntu: sudo apt install ffmpeg, Mac: brew install ffmpeg)
pip install pydub
安装完成后,可以写个简单的测试脚本,看看环境是否正常。
# test_env.py
import requests
from bs4 import BeautifulSoup
import torch
from transformers import pipeline
print(“requests版本:”, requests.__version__)
print(“BeautifulSoup版本:”, BeautifulSoup.__version__)
print(“torch版本:”, torch.__version__)
print(“环境检查通过!”)
运行这个脚本,如果没有报错,说明基础环境OK了。
2. 实战第一步:用Python爬虫抓取音频
假设我们要从一个公开的音频分享网站下载讲座录音。这里的关键是找到网页中音频文件的真实下载地址。
2.1 分析网页与定位音频链接
大多数情况下,音频文件不会直接放在页面的某个链接里,而是通过一个音频播放器来加载。我们需要用浏览器的开发者工具(按F12)查看网络请求,找到那个以 .mp3、.wav 或 .m4a 结尾的请求。
找到地址后,爬虫的工作就是模拟这个请求。下面是一个示例函数,用于抓取单个页面的音频。
import requests
from bs4 import BeautifulSoup
import os
import time
def download_audio_from_page(page_url, save_dir=“downloads”):
“””
从指定页面下载音频文件。
Args:
page_url: 包含音频的网页地址
save_dir: 本地保存目录
“””
headers = {
‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36’
}
try:
# 1. 获取网页内容
response = requests.get(page_url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.content, ‘html.parser’)
# 2. 寻找音频标签 - 这里需要根据目标网站结构调整选择器
# 常见情况:<audio src=“xxx.mp3”> 或 <a href=“xxx.mp3”>下载</a>
audio_tag = soup.find(‘audio’)
if audio_tag and audio_tag.get(‘src’):
audio_url = audio_tag[‘src’]
else:
# 如果不在audio标签里,尝试找包含.mp3等后缀的链接
for link in soup.find_all(‘a’, href=True):
href = link[‘href’]
if href.endswith((‘.mp3’, ‘.wav’, ‘.m4a’, ‘.ogg’)):
audio_url = href
break
else:
print(f”在 {page_url} 中未找到音频链接”)
return None
# 处理相对路径链接
if not audio_url.startswith(‘http’):
from urllib.parse import urljoin
audio_url = urljoin(page_url, audio_url)
# 3. 下载音频文件
os.makedirs(save_dir, exist_ok=True)
# 从链接中提取文件名
filename = os.path.join(save_dir, audio_url.split(‘/’)[-1].split(‘?’)[0])
print(f”正在下载: {audio_url}“)
audio_response = requests.get(audio_url, headers=headers, stream=True, timeout=30)
audio_response.raise_for_status()
with open(filename, ‘wb’) as f:
for chunk in audio_response.iter_content(chunk_size=8192):
f.write(chunk)
print(f”下载完成: {filename}“)
return filename
except Exception as e:
print(f”处理 {page_url} 时出错: {e}“)
return None
# 使用示例
if __name__ == “__main__”:
# 替换成你要抓取的实际页面地址
test_page = “https://example-audio-site.com/lecture/123”
downloaded_file = download_audio_from_page(test_page)
2.2 实现批量爬取
单个页面不够,我们通常需要抓取一个列表页下的所有音频。思路是先爬取列表页,解析出每个音频的详情页链接,再逐个调用上面的下载函数。
def batch_download_from_list(list_url, max_items=5):
“””
从列表页批量下载音频。
Args:
list_url: 音频列表页地址
max_items: 最大下载数量(用于测试)
“””
headers = {‘User-Agent’: ‘Mozilla/5.0 ...’}
try:
resp = requests.get(list_url, headers=headers)
soup = BeautifulSoup(resp.content, ‘html.parser’)
# 假设每个音频条目在一个class为‘audio-item’的div里,包含一个到详情页的链接
# 你需要根据实际网站结构调整选择器
items = soup.find_all(‘div’, class_=‘audio-item’)[:max_items]
downloaded_files = []
for item in items:
link_tag = item.find(‘a’, href=True)
if link_tag:
detail_page_url = urljoin(list_url, link_tag[‘href’])
print(f”\n处理详情页: {detail_page_url}“)
file_path = download_audio_from_page(detail_page_url)
if file_path:
downloaded_files.append(file_path)
# 礼貌爬取,避免给服务器太大压力
time.sleep(1)
print(f”\n批量下载完成,共获取 {len(downloaded_files)} 个文件。”)
return downloaded_files
except Exception as e:
print(f”批量下载失败: {e}“)
return []
跑完这部分,你的 downloads 文件夹里应该就有了一堆原始音频文件。接下来,我们要把它们变成模型认识的格式。
3. 实战第二步:音频预处理与格式统一
从网上抓下来的音频,格式五花八门,采样率也可能不同。Qwen3-ASR模型对输入音频有一定的要求(通常是16kHz采样率的单声道WAV文件),所以预处理这一步不能省。
3.1 用pydub进行格式转换
pydub 库底层依赖 ffmpeg,能非常方便地处理音频格式转换、采样率调整等操作。
from pydub import AudioSegment
import os
def convert_to_wav(input_path, output_dir=“processed_audio”):
“””
将任意格式音频文件转换为16kHz单声道WAV格式。
Args:
input_path: 输入音频文件路径
output_dir: 输出目录
Returns:
转换后的WAV文件路径
“””
os.makedirs(output_dir, exist_ok=True)
# 生成输出文件名
base_name = os.path.splitext(os.path.basename(input_path))[0]
output_path = os.path.join(output_dir, f”{base_name}_processed.wav”)
try:
# 加载音频文件
audio = AudioSegment.from_file(input_path)
# 统一转换为单声道、16kHz采样率
audio = audio.set_channels(1) # 单声道
audio = audio.set_frame_rate(16000) # 16kHz
# 导出为WAV格式
audio.export(output_path, format=“wav”)
print(f”转换成功: {input_path} -> {output_path}“)
return output_path
except Exception as e:
print(f”转换失败 {input_path}: {e}“)
return None
# 批量处理下载文件夹中的所有音频
def batch_process_audio(input_dir=“downloads”, output_dir=“processed_audio”):
processed_files = []
for filename in os.listdir(input_dir):
if filename.lower().endswith((‘.mp3’, ‘.wav’, ‘.m4a’, ‘.flac’, ‘.ogg’)):
input_path = os.path.join(input_dir, filename)
output_path = convert_to_wav(input_path, output_dir)
if output_path:
processed_files.append(output_path)
return processed_files
3.2 处理长音频的拆分问题
语音识别模型通常对单次输入的音频长度有限制。如果遇到很长的讲座录音(比如超过30分钟),直接识别效果可能不好,也容易内存溢出。一个实用的技巧是把长音频切成较短(例如10分钟一段)的片段。
def split_long_audio(input_wav_path, segment_length_ms=600000): # 10分钟 = 600000毫秒
“””
将长音频切分为固定长度的片段。
Args:
input_wav_path: 输入WAV文件路径
segment_length_ms: 每个片段的毫秒数
Returns:
切分后的音频文件路径列表
“””
audio = AudioSegment.from_wav(input_wav_path)
duration_ms = len(audio)
base_name = os.path.splitext(os.path.basename(input_wav_path))[0]
output_dir = os.path.join(os.path.dirname(input_wav_path), “segments”)
os.makedirs(output_dir, exist_ok=True)
segments = []
for i, start_ms in enumerate(range(0, duration_ms, segment_length_ms)):
end_ms = min(start_ms + segment_length_ms, duration_ms)
segment = audio[start_ms:end_ms]
segment_path = os.path.join(output_dir, f”{base_name}_part{i+1:03d}.wav”)
segment.export(segment_path, format=“wav”)
segments.append(segment_path)
print(f”切分片段: {segment_path} ({len(segment)/1000:.1f}s)”)
return segments
预处理完成后,我们就得到了一批干净、格式统一的WAV文件,可以喂给模型了。
4. 实战第三步:调用Qwen3-ASR进行批量识别
这是最核心的一步,我们用 transformers 库加载Qwen3-ASR-1.7B模型,对处理好的音频进行识别。
4.1 初始化识别管道
第一次运行时会下载模型,需要一点时间和网络。
from transformers import pipeline
import torch
def init_asr_pipeline(model_name=“Qwen/Qwen3-ASR-1.7B”):
“””
初始化语音识别管道。
Note: 模型较大,首次运行需下载,请保持网络通畅。
“””
print(f”正在加载模型 {model_name},首次使用可能需要几分钟下载...”)
# 根据你的硬件情况,可以决定是否使用GPU
device = 0 if torch.cuda.is_available() else -1
try:
# 创建自动语音识别管道
asr_pipe = pipeline(
“automatic-speech-recognition”,
model=model_name,
device=device
)
print(“模型加载成功!”)
return asr_pipe
except Exception as e:
print(f”模型加载失败: {e}“)
# 如果网络问题,可以尝试从本地路径加载(如果你提前下载了模型)
# asr_pipe = pipeline(“automatic-speech-recognition”, model=“./local_qwen_asr_model”)
return None
4.2 执行批量识别并保存结果
加载好管道后,我们就可以遍历所有处理过的音频文件,进行识别,并把结果保存到文本文件或结构化的数据(如JSON)中。
import json
def batch_transcribe(audio_file_list, asr_pipe, output_json=“transcription_results.json”):
“””
批量识别音频文件。
Args:
audio_file_list: 音频文件路径列表
asr_pipe: 初始化好的ASR管道
output_json: 结果输出文件
“””
results = []
for audio_path in audio_file_list:
print(f”\n识别中: {os.path.basename(audio_path)}“)
try:
# 调用模型进行识别
# generate_kwargs 可以传递一些生成参数,比如beam search的大小
transcription = asr_pipe(
audio_path,
generate_kwargs={“num_beams”: 5} # 使用束搜索,可能提升准确率
)
text = transcription[‘text’].strip()
result = {
“audio_file”: os.path.basename(audio_path),
“file_path”: audio_path,
“transcription”: text,
“duration”: get_audio_duration(audio_path) # 需要实现这个辅助函数
}
results.append(result)
print(f”识别结果: {text[:100]}...“) # 打印前100字符预览
except Exception as e:
print(f”识别失败 {audio_path}: {e}“)
results.append({
“audio_file”: os.path.basename(audio_path),
“error”: str(e)
})
# 将结果保存到JSON文件
with open(output_json, ‘w’, encoding=‘utf-8’) as f:
json.dump(results, f, ensure_ascii=False, indent=2)
print(f”\n所有识别完成!结果已保存至 {output_json}“)
return results
def get_audio_duration(audio_path):
“””获取音频文件时长(秒)。“””
try:
audio = AudioSegment.from_wav(audio_path)
return len(audio) / 1000.0 # 毫秒转秒
except:
return 0
4.3 串联整个流程
最后,我们写一个主函数,把爬取、处理、识别这三个步骤串起来,形成一个完整的自动化脚本。
def main_pipeline(list_url, max_downloads=3):
“””
从音频列表页开始,执行完整的采集、处理、识别流程。
Args:
list_url: 起始列表页URL
max_downloads: 最大下载数量(用于演示)
“””
print(“=== 步骤1: 批量下载音频 ===”)
raw_files = batch_download_from_list(list_url, max_items=max_downloads)
print(“\n=== 步骤2: 音频预处理与格式转换 ===”)
processed_files = batch_process_audio(“downloads”, “processed_audio”)
# 可选:处理长音频拆分
final_audio_list = []
for p_file in processed_files:
# 如果音频超过15分钟,进行切分
if get_audio_duration(p_file) > 900:
segments = split_long_audio(p_file)
final_audio_list.extend(segments)
else:
final_audio_list.append(p_file)
print(f”\n待识别音频文件数: {len(final_audio_list)}“)
print(“\n=== 步骤3: 加载语音识别模型 ===”)
asr_pipe = init_asr_pipeline()
if not asr_pipe:
print(“模型加载失败,流程终止。”)
return
print(“\n=== 步骤4: 批量语音识别 ===”)
results = batch_transcribe(final_audio_list, asr_pipe)
print(“\n=== 流程全部完成 ===")
# 这里可以添加一些简单的结果分析,比如统计总时长、平均识别速度等
total_duration = sum(r.get(‘duration’, 0) for r in results if ‘duration’ in r)
print(f”处理音频总时长: {total_duration/60:.2f} 分钟”)
# 运行示例(请替换为真实的列表页URL)
if __name__ == “__main__”:
# 请务必遵守目标网站的robots.txt协议,并用于合法合规的学习研究目的
target_list_url = “https://example.com/audio-lectures”
main_pipeline(target_list_url, max_downloads=2)
跑完这个脚本,你会在当前目录下得到一个 transcription_results.json 文件,里面就是所有音频识别出来的文字内容,结构清晰,方便你后续做分析、搜索或者存档。
5. 总结
走完这一整套流程,你会发现,把Python爬虫和Qwen3-ASR模型结合起来,处理网络音频数据其实没那么复杂。爬虫负责把散落在各处的音频资源自动化收集起来,模型则负责把声音转化为可编辑、可分析的文字。这套方法特别适合需要处理大量语音资料的场景,比如媒体内容分析、在线教育课程整理、会议纪要生成等等。
实际用下来,Qwen3-ASR-1.7B在中文语音识别上的表现挺扎实的,对于发音清晰的讲座、播客内容,准确率很有保障。当然,如果音频背景噪音比较大,或者有很重的口音,效果可能会打折扣,这是目前所有语音识别模型都面临的挑战。
有几个小建议给想尝试的朋友:一是爬取数据时一定要有节制,遵守网站的规则,别把别人服务器搞挂了;二是对于非常重要的识别任务,最好能加入一个人工复查的环节,机器识别完再快速过一遍,确保关键信息无误;三是可以尝试把识别后的文本,进一步用大语言模型做摘要、提炼要点,这样数据的价值就被层层挖掘出来了。
希望这个实战指南能帮你打开思路。自动化工具的意义就是把人从重复劳动里解放出来,让我们能更专注于那些真正需要创造力和判断力的工作。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐

所有评论(0)