parse-cosyvoice-dom.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """parse-cosyvoice-dom.py — 解析阿里云 CosyVoice 音色页面 DOM,输出 JSON + 摘要"""
  4. import re
  5. import json
  6. import sys
  7. from collections import defaultdict
  8. PATH = r"C:/Users/caoyg/AppData/Local/Temp/cosyvoice.html"
  9. text = open(PATH, encoding='utf-8').read()
  10. # 切分 4 个模型段
  11. SECTIONS = [
  12. ('cosyvoice-v3-flash', r'cosyvoice-v3-flash音色列表(.*?)cosyvoice-v3-plus音色列表'),
  13. ('cosyvoice-v3-plus', r'cosyvoice-v3-plus音色列表(.*?)(?=下一篇|cosyvoice-v2音色列表)'),
  14. ('cosyvoice-v2', r'cosyvoice-v2音色列表(.*?)cosyvoice-v1音色列表'),
  15. ('cosyvoice-v1', r'cosyvoice-v1音色列表(.*?)(?=上一篇|下一篇|\Z)'),
  16. ]
  17. all_models = {}
  18. for model, pat in SECTIONS:
  19. m = re.search(pat, text, re.DOTALL)
  20. if not m:
  21. continue
  22. section = m.group(1)
  23. voices = []
  24. positions = [mm.start() for mm in re.finditer(r'名称[::]\s*.+?\n', section)]
  25. positions.append(len(section))
  26. for i in range(len(positions) - 1):
  27. chunk = section[positions[i]:positions[i+1]]
  28. voice = {}
  29. n = re.search(r'^名称[::]\s*(.+?)\s*$', chunk, re.MULTILINE)
  30. if n: voice['name'] = n.group(1).strip()
  31. v = re.search(r'voice参数[::]\s*(\w+)', chunk)
  32. if v: voice['voice_id'] = v.group(1)
  33. t = re.search(r'特质[::]\s*(.+?)\n', chunk)
  34. if t: voice['desc'] = t.group(1).strip()[:80]
  35. a = re.search(r'年龄[::]\s*(.+?)\n', chunk)
  36. if a: voice['age'] = a.group(1).strip()
  37. l = re.search(r'语言[::]\s*(.+?)\n', chunk)
  38. if l: voice['lang'] = l.group(1).strip()[:60]
  39. voice['instruct'] = '支持' if 'Instruct:支持' in chunk else '不支持' if 'Instruct:不支持' in chunk else '?'
  40. # scene/地区
  41. s = re.search(r'适用场景[::]\s*(.+?)\n', chunk)
  42. if s: voice['scene'] = s.group(1).strip()[:40]
  43. if voice.get('name'):
  44. voices.append(voice)
  45. all_models[model] = voices
  46. # 输出 JSON
  47. with open(r"C:/Users/caoyg/AppData/Local/Temp/cosyvoice-voices.json", "w", encoding="utf-8") as f:
  48. json.dump(all_models, f, ensure_ascii=False, indent=2)
  49. # 输出摘要
  50. sys.stdout.reconfigure(encoding='utf-8')
  51. for model, voices in all_models.items():
  52. print(f"\n=== {model}: {len(voices)} 个音色 ===")
  53. lang_count = defaultdict(int)
  54. for v in voices:
  55. lang = v.get('lang', '?')
  56. # 简化为第一个语种
  57. first = lang.split('、')[0].split('(')[0]
  58. lang_count[first] += 1
  59. print(f" 语种分布:")
  60. for lang, cnt in sorted(lang_count.items(), key=lambda x: -x[1]):
  61. print(f" {lang}: {cnt}")