| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """parse-cosyvoice-dom.py — 解析阿里云 CosyVoice 音色页面 DOM,输出 JSON + 摘要"""
- import re
- import json
- import sys
- from collections import defaultdict
- PATH = r"C:/Users/caoyg/AppData/Local/Temp/cosyvoice.html"
- text = open(PATH, encoding='utf-8').read()
- # 切分 4 个模型段
- SECTIONS = [
- ('cosyvoice-v3-flash', r'cosyvoice-v3-flash音色列表(.*?)cosyvoice-v3-plus音色列表'),
- ('cosyvoice-v3-plus', r'cosyvoice-v3-plus音色列表(.*?)(?=下一篇|cosyvoice-v2音色列表)'),
- ('cosyvoice-v2', r'cosyvoice-v2音色列表(.*?)cosyvoice-v1音色列表'),
- ('cosyvoice-v1', r'cosyvoice-v1音色列表(.*?)(?=上一篇|下一篇|\Z)'),
- ]
- all_models = {}
- for model, pat in SECTIONS:
- m = re.search(pat, text, re.DOTALL)
- if not m:
- continue
- section = m.group(1)
- voices = []
- positions = [mm.start() for mm in re.finditer(r'名称[::]\s*.+?\n', section)]
- positions.append(len(section))
- for i in range(len(positions) - 1):
- chunk = section[positions[i]:positions[i+1]]
- voice = {}
- n = re.search(r'^名称[::]\s*(.+?)\s*$', chunk, re.MULTILINE)
- if n: voice['name'] = n.group(1).strip()
- v = re.search(r'voice参数[::]\s*(\w+)', chunk)
- if v: voice['voice_id'] = v.group(1)
- t = re.search(r'特质[::]\s*(.+?)\n', chunk)
- if t: voice['desc'] = t.group(1).strip()[:80]
- a = re.search(r'年龄[::]\s*(.+?)\n', chunk)
- if a: voice['age'] = a.group(1).strip()
- l = re.search(r'语言[::]\s*(.+?)\n', chunk)
- if l: voice['lang'] = l.group(1).strip()[:60]
- voice['instruct'] = '支持' if 'Instruct:支持' in chunk else '不支持' if 'Instruct:不支持' in chunk else '?'
- # scene/地区
- s = re.search(r'适用场景[::]\s*(.+?)\n', chunk)
- if s: voice['scene'] = s.group(1).strip()[:40]
- if voice.get('name'):
- voices.append(voice)
- all_models[model] = voices
- # 输出 JSON
- with open(r"C:/Users/caoyg/AppData/Local/Temp/cosyvoice-voices.json", "w", encoding="utf-8") as f:
- json.dump(all_models, f, ensure_ascii=False, indent=2)
- # 输出摘要
- sys.stdout.reconfigure(encoding='utf-8')
- for model, voices in all_models.items():
- print(f"\n=== {model}: {len(voices)} 个音色 ===")
- lang_count = defaultdict(int)
- for v in voices:
- lang = v.get('lang', '?')
- # 简化为第一个语种
- first = lang.split('、')[0].split('(')[0]
- lang_count[first] += 1
- print(f" 语种分布:")
- for lang, cnt in sorted(lang_count.items(), key=lambda x: -x[1]):
- print(f" {lang}: {cnt}")
|