Python实战:开发在线小说语音阅读器

蓝鲸
蓝鲸
发布时间:2026-10-13 | 4人浏览过
原创

本文详解如何使用Python开发一款小说语音阅读器。通过百度AI开放平台获取语音合成API,结合requests和lxml从笔趣阁抓取小说章节,并利用pygame库实现内存中音频的实时播放。文章涵盖API配置、网页解析、音频参数设置及代码实现,帮助开发者快速构建本地听书工具。

项目背景与需求分析

前言

此前在书荒期间,我在喜马拉雅APP上发现了一部由主播演播的小说《大王饶命》。虽然听感有趣且轻松,但该平台仅开放前200章免费,后续章节需付费收听。单章费用为0.2元,全书共计1300多章,总计需支付约260元。此外,主播更新速度较慢,等待完整收听的时间成本过高。

因此,我转向寻找文字版小说。然而,阅读文字版需要手眼协调,难以兼顾其他事务,且无法缓解想要继续阅读的冲动。经过网络搜索,未找到其他免费音频资源。同时,以往常用的具备阅读功能的软件(如微信阅读、追书神器等)也逐渐转向收费模式。

面对这一困境,作为Python开发者,这显然难不倒我们。既然掌握了Python这一高效工具,不妨借此机会实践一下编程技能。


秉持“自己动手,丰衣足食”的理念,接下来将利用Python技术栈构建一个专属的小说阅读器。

语音合成技术选型

语音合成方案选择

实现文字转语音的核心在于语音合成技术。目前市面上较为成熟的方案包括讯飞和百度语音,本文选用百度语音合成API进行实现。

创建语音合成应用

首先,需注册百度账号并登录百度AI开放平台,在控制台创建一个新应用。

填写应用名称及描述信息后提交申请。


创建成功后,务必记录AppID、API Key和Secret Key,这些凭证将在调用API时使用。同时,查阅相关技术文档以了解接口规范。

通过命令pip install baidu-aip安装百度AI Python SDK。文档中提供了详细的示例代码,便于快速上手。SDK支持调节音量、语调、语速及发声人等参数。至此,语音合成环节已准备就绪,下一步是获取小说文本内容。

小说数据抓取与解析

小说内容获取策略

小说数据源选取自笔趣阁网站,主要考量因素为内容免费且反爬机制较弱。首先定位到目标小说的首页地址。

以链接https://www.biquge.info/40_40289/为例,使用requests库发起HTTP请求即可获取页面数据。对页面结构进行简要分析。

所有章节链接均位于dl标签下的dd元素中,且链接结构具有规律性,可直接使用xpath提取所有章节列表信息。


def get_chapters(self):
 url = "https://www.biquge.info/40_40289/"
 r = self.session.get(url)
 r.encoding = chardet.detect(r.content).get("encoding", "utf-8")
 html = etree.HTML(r.text)
 for item in html.xpath("//dl/dd/a"):
 yield item.attrib["title"], url + item.attrib["href"]

章节具体内容的获取逻辑相对简单,此处不再赘述。


def get_content(self, url):
 r = self.session.get(url)
 r.encoding = chardet.detect(r.content).get("encoding", "utf-8")
 html = etree.HTML(r.text)
 title = html.xpath(r'//*[@class="bookname"]/h1')[0].text
 for info in html.xpath("//div[@id='content']"):
 text = info.xpath("string(.)")

需注意,提取的章节内容中可能包含HTML标签。xpath提供的string(.)函数可有效提取多个子节点的纯文本,非常实用。

音频合成与播放实现

语音合成与数据存储

将获取的小说内容与语音合成模块结合,即可形成小说阅读器的基本雏形。基础实现逻辑如下:


import chardet
import requests
from lxml import etree
from aip import AipSpeech
class CollectNovels:
 def __init__(self):
 self.session = requests.session()
 self.session.headers["user-agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
 """ 你的 APPID AK SK """
 APP_ID = '16416498'
 API_KEY = 'oEWGafQkaUGqmsmPbfkE5OMx'
 SECRET_KEY = '6jdsUcH0PXz5TYoELU47u58W5vPV9lwf'
 self.client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
 def get_chapters(self, url):
 r = self.session.get(url)
 r.encoding = chardet.detect(r.content).get("encoding", "utf-8")
 html = etree.HTML(r.text)
 for item in html.xpath("//dl/dd/a"):
 yield item.attrib["title"], url + item.attrib["href"]
 def get_content(self, url):
 r = self.session.get(url)
 r.encoding = chardet.detect(r.content).get("encoding", "utf-8")
 html = etree.HTML(r.text)
 for info in html.xpath("//div[@id='content']"):
 text = info.xpath("string(.)")
 for line in text.split("。"):
 content = self.client.synthesis(line, 'zh', 1, {"per": 0})
 with open("auido.mp3", "rb") as fp:
 fp.write(content)
if __name__ == '__main__':
 novel = CollectNovels()
 home_url = "https://www.biquge.info/40_40289/"
 for title, url in novel.get_chapters(home_url):
 novel.get_content(url)

上述代码生成mp3文件,按行生成后通过合成软件处理,虽可存储于任意位置播放,但存在需预先完整生成才能播放的缺陷,使用体验不够便捷。若能实现边生成边播放,体验将更佳。

实时播放合成语音方案

推荐使用Python的pygame库进行音频播放。其他几个音频库要么效果不佳,要么已长期未维护,故不予采用。


import time
import pygame
from io import BytesIO
pygame_mixer = pygame.mixer
pygame_mixer.init(frequency=frequency)
byte_obj = BytesIO()
byte_obj.write(content)
byte_obj.seek(0, 0)
pygame_mixer.music.load(byte_obj)
pygame_mixer.music.play()
while pygame_mixer.music.get_busy():
 time.sleep(0.1)
pygame_mixer.stop()

利用BytesIO类将语音合成的二进制数据存储在内存中,从而避免生成本地mp3文件,节省磁盘空间。

关键注意点:调用pygame_mixer.init(frequency=frequency)时,必须设置frequency参数。若不设置,默认频率为22050,导致播放音质与mp3差异巨大。此前因怀疑库有问题而尝试多个库,最终发现需调整此参数。该参数值可从之前生成的mp3文件属性中获取。


将频率参数设置为16000即可获得较好音质。

以上即为本文的全部内容,希望对读者的学习有所帮助,也欢迎大家继续支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表