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

使用ai的方法给epub文件中的汉字加拼音

前言

方便小孩阅读,对epub文件加拼音。

使用ai的方法解决多音字问题。

方法

使用python中调用ai的方法。

(1)Python环境的安装,这里直接安装python3.0以上:

https://www.python.org/downloads/windows/

image

安装时需要打勾添加进系统环境变量。

在cmd中确认是否安装完毕:出现下述界面表示python环境部署完毕。

image

(2)安装相关的库:

> pip install openai ebooklib bs4 pypinyin

(3)在文件夹下增加此代码文件add_pinyin_doubao.py,内容如下:

# -*- coding: utf-8 -*-
# add_pinyin_doubao.py —— 2025-12-07 终极无敌永不崩溃版
# 豆包一键加注音神器,10万字小说 25~35 秒出书,兼容一切 EPUB!import os
import re
import time
import threading
import uuid
from concurrent.futures import ThreadPoolExecutor, as_completed
from openai import OpenAI
from ebooklib import epub
from bs4 import BeautifulSoup
from pypinyin import pinyin, Style# ====================== 配置区 ======================
os.environ["ARK_API_KEY"] = ""  # ← 填你的豆包 Key!# 一键切换模型(改这一行就行)
MODEL_NAME = "doubao-1-5-pro-32k-250115"           # Pro:最准
# MODEL_NAME = "doubao-seed-1-6-flash-250828"      # Seed:最快最省(推荐)
# MODEL_NAME = "doubao-seed-1-6-lite-250828"       # 最便宜MAX_WORKERS = 128
API_CONCURRENCY = 256
API_RETRY = 3
SLEEP_AFTER_API = 0.06
# ====================================================client = OpenAI(base_url="https://ark.cn-beijing.volces.com/api/v3",api_key=os.environ.get("ARK_API_KEY"),timeout=60
)PROMPT = """请把下面这段话转换成纯拼音(头顶带声调符号),一个汉字严格对应一个拼音,用空格隔开。
不要出现任何标点符号,轻声写原音节(如吗→ma),ü 一定要带点:ǖǘǚǜ例如:
我叫李华,住在“长寿桥”。
→ wǒ jiào lǐ huá zhù zài cháng shòu qiáo现在转换:
{text}"""api_sema = threading.Semaphore(API_CONCURRENCY)
PINYIN_RE = re.compile(r'[āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜüa-zA-Z]+')
PUNCT_CHARS = r'''!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~,。!?;:、“”‘’()【】《》'''
punctuation_pattern = f'[{re.escape(PUNCT_CHARS)}]'def num2tone(s):tone_map = {'a': 'āáǎà', 'o': 'ōóǒò', 'e': 'ēéěè', 'i': 'īíǐì', 'u': 'ūúǔù', 'ü': 'ǖǘǚǜ'}s = s.replace('v', 'ü')m = re.match(r'^([a-zü]+)(\d)$', s, re.I)if not m:return sbase, tone = m.group(1).lower(), int(m.group(2))for ch in 'aoeiuü':if ch in base:return base.replace(ch, tone_map[ch][tone - 1] if tone <= 4 else ch)return basedef local_pinyin_fallback(text: str):raw = pinyin(text, style=Style.TONE3, heteronym=False, errors='ignore')return [num2tone(item[0]) if item else '' for item in raw]def api_get_pinyin_list(text):for attempt in range(1, API_RETRY + 1):if not api_sema.acquire(timeout=60):return local_pinyin_fallback(text)try:resp = client.chat.completions.create(model=MODEL_NAME,messages=[{"role": "user", "content": PROMPT.format(text=text)}],temperature=0.0,max_tokens=4096)raw = resp.choices[0].message.content.strip()lst = PINYIN_RE.findall(raw.lower())lst = [p.replace('v', 'ü') for p in lst]time.sleep(SLEEP_AFTER_API)return lstexcept Exception as e:print(f"\n[第{attempt}次] API调用失败: {e}")if attempt == API_RETRY:print("→ 改用本地pypinyin兜底")return local_pinyin_fallback(text)time.sleep(2 ** (attempt - 1))finally:api_sema.release()return []def text_to_ruby_local(text: str) -> str:chinese_chars = [c for c in text if '\u4e00' <= c <= '\u9fff']if not chinese_chars:return textmarks = []clean_text = re.sub(punctuation_pattern, lambda m: (marks.append(m.group()), "__MARK__")[1], text)py_list = api_get_pinyin_list(clean_text)if len(py_list) != len(chinese_chars):py_list = local_pinyin_fallback(clean_text)result = []py_idx = 0i = 0while i < len(text):ch = text[i]if re.match(punctuation_pattern, ch):result.append(ch)elif '\u4e00' <= ch <= '\u9fff':py = py_list[py_idx] if py_idx < len(py_list) else ''result.append(f"<ruby><rb>{ch}</rb><rt>{py}</rt></ruby>")py_idx += 1else:result.append(ch)i += 1return ''.join(result)def is_html_item(item):return (hasattr(epub, 'ITEM_DOCUMENT') and item.get_type() == epub.ITEM_DOCUMENT) or \getattr(item, 'media_type', '').startswith('application/xhtml+xml')# ====================== 永久解决所有 write_epub 崩溃的核心函数 ======================
def fix_epub_before_write(book):"""彻底解决 uid/None/ncx/Chapter 等所有历史遗留崩溃问题"""# 1. 修复所有 item 的 uid 和 file_namefor item in book.get_items():if not getattr(item, 'uid', None):item.uid = str(uuid.uuid4())if not getattr(item, 'file_name', None):item.file_name = f"{item.uid}.xhtml"# 2. 递归修复 TOC(只认 Section 和 Link!)def walk_toc(items):if not items:returnfor item in items:if isinstance(item, epub.Section):if not getattr(item, 'uid', None):item.uid = str(uuid.uuid4())elif isinstance(item, epub.Link):if not getattr(item, 'uid', None):item.uid = str(uuid.uuid4())elif isinstance(item, tuple) and len(item) >= 1:walk_toc([item[0]])if len(item) > 1:walk_toc(item[1:])elif hasattr(item, '__iter__') and not isinstance(item, str):walk_toc(item)walk_toc(book.toc)# 3. 终极保险:禁用老旧 ncx(现代阅读器全靠 nav.xhtml)try:book.set_option('no_ncx', True)except:pass  # 老版本 ebooklib 没有这个选项,直接忽略def main():print("豆包拼音添加器 2025.12 终极无敌永不崩溃版 启动!")epubs = [f for f in os.listdir('.') if f.lower().endswith('.epub') and '_终极拼音' not in f]if not epubs:print("没找到epub文件,请把小说epub拖到这个文件夹")input("回车退出...")returnsrc = epubs[0]dst = src.replace('.epub', '_终极拼音.epub')print(f"使用模型:{MODEL_NAME}")print(f"处理:{src} → {dst}")book = epub.read_epub(src)entries = []item_map = {}for item in book.get_items():if not is_html_item(item):continuehref = getattr(item, 'file_name', f"item_{id(item)}.xhtml")item_map[href] = itemsoup = BeautifulSoup(item.get_content(), 'html.parser')for idx, p_tag in enumerate(soup.find_all('p')):text = p_tag.get_text()if text.strip():entries.append((href, idx, text))total = len(entries)print(f"发现 {total} 段,开始并行加拼音...")results = []with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:future_to_info = {executor.submit(text_to_ruby_local, text): (href, idx)for href, idx, text in entries}for future in as_completed(future_to_info):href, idx = future_to_info[future]try:ruby_text = future.result()results.append((href, idx, ruby_text))except Exception as e:print(f"\n段落处理异常: {e},保留原文")results.append((href, idx, text))print(f"\r进度:{len(results)}/{total} ({len(results)/total*100:.1f}%)", end="")print("\n\n写回EPUB...")# 关键修复:永别 uid/ncx 崩溃!fix_epub_before_write(book)from collections import defaultdictgrouped = defaultdict(list)for href, idx, ruby in results:grouped[href].append((idx, ruby))for href, items in grouped.items():item = item_map.get(href)if not item:continuesoup = BeautifulSoup(item.get_content(), 'html.parser')p_tags = soup.find_all('p')for idx, ruby in sorted(items):if idx < len(p_tags):p_tags[idx].clear()p_tags[idx].append(BeautifulSoup(ruby, 'html.parser'))item.set_content(str(soup).encode('utf-8'))epub.write_epub(dst, book)print(f"\n成功!生成:{dst}")try:os.startfile(dst)print("已自动打开文件,快欣赏你的带拼音神书吧!")except:print("请手动打开输出文件查看")input("\n按回车退出...")if __name__ == "__main__":main()

(4)把需要增加拼音的书籍放置在py代码的同级目录:

image

(5)在命令行中执行:

 >  python .\add_pinyin_doubao.py

image

等待完成。

结果

image

image

Note

注意,拼音的多音字准确性取决于大模型,测试下来,豆包pro,seed系列都是准的,推荐使用doubao-1-5-pro-32k

deepseek不准,对有些多音字识别有问题。

http://www.zskr.cn/news/76966.html

相关文章:

  • [ABC194C] Squared Error
  • 基于SIFT的交通标志识别系统设计与GUI实现
  • 2025年杭州中央空调品牌推荐:商用中央空调选哪家?5大靠谱
  • 2025年广州结构加固改造公司权威推荐榜单:厂房加固改造‌/加固改造‌/房屋加固改造‌‌源头公司精选
  • 长途搬家物流公司推荐!上海跨省搬家到北京、杭州、深圳、广州搬家公司推荐!
  • 2025年工业火花塞厂家排名:工业火花塞厂家哪家靠谱
  • 单径瑞利信道与多径瑞利信道仿真
  • 2025年成核剂母粒定制厂家权威推荐榜单:PP低卤阻燃母粒/特种橡塑发泡剂/发泡添加剂源头厂家精选
  • 2025年GEO优化服务商推荐:AI时代流量突围的优质之选
  • 芯动园林景观设计:靠谱之选,打造理想景观空间
  • 2025年洁净车间口碑榜TOP5:洁净车间/净化车间哪家口碑
  • 改进遗传算法求解VRP问题的局部搜索能力优化方案
  • 2025英国好的留学中介
  • 2025 年除沫器厂家最新推荐榜,技术实力与市场口碑深度解析,助力企业精准采购优质设备聚四氟乙烯丝网/PP 丝网/钛丝网/不锈钢/PTFE 丝网/聚丙烯丝网/折流板/波浪形抽屉除沫器公司推荐
  • 2025英国留学中介机构排名北京
  • 2025 年分布器厂家最新推荐榜,聚焦企业技术研发实力与市场应用口碑深度解析槽式液体/管式液体/塔内件/管式/液体再/全连通液体/二级槽式/液体收集再分布器公司推荐
  • 2025 年 12 月食堂承包服务商权威推荐榜:专业运营与高效供餐,大型饭堂/食堂承包解决方案深度解析
  • 2025年云南住宅修缮服务推荐:昆明曲靖玉溪靠谱的房屋修缮公
  • 2025年度重庆电力总包资质代办和转让五大推荐,看哪家公司实
  • 2025年度设备安全锁推荐厂商TOP5:专业供应商实力解析与
  • 2025 年 12 月食堂送菜服务商权威推荐榜:新鲜直达、高效配送与智慧供应链管理口碑之选
  • AO3401-ASEMI低压控制领域核芯组件AO3401
  • 高考教育信息智能助手 API 接口
  • 2025 年 12 月精品包装盒,礼盒包装盒厂家最新推荐,产能、专利、环保三维数据透视!
  • Gartner发布2026年战略趋势:当AI重塑一切,你的业务流程还跟得上吗?(附报告原文下载)
  • 紧急!Next.js高危漏洞致服务器被黑,我已经中招了!附解决方案
  • 2025英国出国留学中介排名
  • Transformer 详解:从架构到训练
  • CISA速通(二)IT治理与管理
  • 2025年市面上排行前列的石笼网厂商哪个好,柔韧抗压石笼网/双隔板石笼网/锌铝合金石笼网/镀锌低碳钢丝石笼网/六角石笼网厂商推荐