前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python爬虫实例十七:爬取王者荣耀英雄语音

Python爬虫实例十七:爬取王者荣耀英雄语音

原创
作者头像
远方的星
修改2021-08-17 18:07:35
3.5K0
修改2021-08-17 18:07:35
举报

写在前面

很久之前就萌生了想爬取王者荣耀英雄台词语音,因为语音资源不是很好找,从官网获得的话,也比较麻烦。最近刚好有朋友需要语音素材,于是我就顺便帮了他一把。

完成这次爬虫,前前后后大概花了8个小时左右,用了之前没用到的库,和一些函数用法,导致bug,以至于花费时间来解决。而且因为自己过于盲目地爬取,一开始没有具体分析,到后来慢慢完善,总共写了三个版本。通过这次的练习,自己也有些许收获。

第一个版本,写一半发现,爬取失败;

第二个版本,能够顺利爬取语音及相关文本,但是不够全面;

第三个版本,顺利地爬取了全部语音及相关文本,并进行合理地合成,方便欣赏。

本文主要介绍第三个版本。

环境

  • python3.9
  • pycharm

网页分析

首先来到含有英雄全部语音的页面

https://pvp.qq.com/story201904/index.html#/voice?id=144

进入网页后,进行检查,如下图,找到data_zlk_lb.json这个文件,可以很清晰的见到想要爬取的台词语音及相关的文本。

在这里插入图片描述
在这里插入图片描述

切换到标头,即可找到需要的URL

在这里插入图片描述
在这里插入图片描述

到这,目标一就找到了。

  • 如:取一个语音的MP3文件链接,做演示 //game.gtimg.cn/images/yxzj/zlkdatasys/audios/audio/20210406/16177204029921.mp3
    在这里插入图片描述
    在这里插入图片描述
    这八秒的语音对应的台词就是:==你好,我叫艾琳!==

有了目标一,是不是有小伙伴想问,难道还有目标二?

当然!因为在这个页面,除了这些,我们最多还能得到的是声优的信息,和英雄的编号,得不到英雄的名称,不方便最后文件的命名。

为了提高最后文件的可读性,最好能够台词与英雄名相匹配。

匹配的关键桥梁就是,英雄编号!

可以来到第二个详情页:英雄资料页面

https://pvp.qq.com/web201605/herolist.shtml

==其实,我之前有写过一篇关于这个页面的内容爬取,可以参考一下:==

python爬取王者荣耀英雄的背景故事

这样就完成了目标二。

更多的思路体现在代码的注释中

爬虫代码实现及说明

代码语言:txt
复制
# -*- coding: UTF-8 -*-
"""
# @Time: 2021/8/10 12:13
# @Author: 远方的星
# @CSDN: https://blog.csdn.net/qq_44921056
"""
import os
import re
import json
import requests
import chardet
from pydub import AudioSegment
from fake_useragent import UserAgent

# 随机产生请求头
ua = UserAgent(verify_ssl=False, path='D:/Pycharm/fake_useragent.json')

# 提前创建一个文件夹,方便创建子文件夹
path_f = "./王者语音"
if not os.path.exists(path_f):
    os.mkdir(path_f)


# 随机切换请求头
def random_ua():
    headers = {
        "accept-encoding": "gzip",  # gzip压缩编码  能提高传输文件速率
        "user-agent": ua.random
    }
    return headers


#  创建文件夹
def path_creat(name):
    _path = "./王者语音/{}/".format(name)
    if not os.path.exists(_path):
        os.mkdir(_path)
    return _path


#  下载语音内容
def download(file_name, text, path):  # 下载函数
    file_path = path + file_name
    with open(file_path, 'wb') as f:
        f.write(text)
        f.close()


#  获取英雄名称及对应编号
def get_hero_num():
    url = 'https://pvp.qq.com/web201605/js/herolist.json'
    response = requests.get(url=url, headers=random_ua()).text
    hero_list = re.findall('"ename": (.+?),', response, re.S)  # 得到英雄的编号列表
    hero_name = re.findall('"cname": "(.+?)"', response, re.S)  # 得到英雄的名字列表
    return hero_list, hero_name


def text_json():
    url = 'https://pvp.qq.com/zlkdatasys/data_zlk_lb.json'
    param = {
        'callback': 'createList'
    }

    res = requests.get(url=url, headers=random_ua(), params=param)
    res.encoding = chardet.detect(res.content)['encoding']
    res = res.text.replace('createList(', '').replace(')', '')  # 去掉不符合json格式的部分字符串数据

    res_json = json.loads(res)  # 将字符串json格式化

    hero = res_json["yylb_34"]  # 所有英雄语音信息
    return hero


# 处理台词文本
def text_deal(text):
    text_result = ''  # 为台词连接做准备
    for j in range(len(text)):
        text_result += text[j]  # 将台词连起来
        text_result += '\n\n'  # 加一个断句的换行符
    text_result = text_result.encode(encoding='utf-8')
    return text_result


def main():
    hero_list, hero_name = get_hero_num()  # 获取英雄编号及名称
    hero_s = text_json()
    for i in range(len(hero_s)):  # len(hero_s)
        hero = hero_s[i]["yxid_a7"]  # 英雄编号

        hero_index = hero_list.index(hero)  # 获取英雄名称对应的索引
        name_result = hero_name[hero_index]  # 确定英雄名称

        path = path_creat(name_result)  # 创建子文件夹

        voice_list = hero_s[i]["yy_4e"]  # 语音列表

        num = 1
        text = []
        silence = AudioSegment.silent(duration=1000)  # 1秒的空期

        try:  # 有部分英雄的语音合成会失败
            for j in range(len(voice_list)):
                voice_text = voice_list[j]["yywa1_f2"]  # 语音文本
                text.append(voice_text)  # 拼接文本

                voice_url = 'http:' + voice_list[j]["yyyp_9a"]  # 语音mp3的url
                voice = requests.get(url=voice_url, headers=random_ua()).content
                voice_name = name_result + '{}.mp3'.format(num)
                download(voice_name, voice, path)  # 下载单个语音
                sound = AudioSegment.from_file(path + voice_name, format="mp3")  # 读取下载的MP3文件
                silence += sound  # 语音合成
                num += 1
            silence.export(path + '{}.mp3'.format(name_result), format="mp3")  # 导出合成语音
            print('{}语音合成成功\n'.format(name_result))
        except:
            print('{}语音合成失败\n'.format(name_result))
        text_result = text_deal(text)  # 最终的文本
        text_name = name_result + '.txt'  # 语音文本文件名称
        download(text_name, text_result, path)  # 下载语音文本
        print("{}的语音文本信息下载完毕!\n".format(name_result))


if __name__ == '__main__':
    main()
  • 运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • 代码的简单说明:

①、对于fake_useragent这个库,可以参考

Python爬虫有用的库:fake_useragent,自动生成请求头

②、对于chardet这个库,可以参考

Python爬虫有用的库:chardet,自动检测字符编码

③、对于pydub这个库,可以参考

Python爬虫有用的库:pydub,处理音视频的库

④、为什么提前创立path_f = "./王者语音"

在练习的过程中,我发现,使用os.mkdir只方便创建下一个等级的目录,而我需要两级,所以提前创立了一个。

⑤、json.loads(),将字符串格式化

可以提前将爬取的txt文件,放到json在线解析,尝试一下。工具很多,

如:https://www.json.cn/

基本上出错的原因都是格式错误,常见的错误有,是""而不是''。本文中遇到的错误是,多了几个字符串,用replace替换掉,或者删除掉都可以,本文采取的替换。

  • 其它说明

①、通过本文爬虫,可以帮助你了解 json 数据的解析和提取需要的数据。

②、本文利用 Python 爬虫一键下载王者荣耀英雄台词语音,实现过程中也会遇到一些问题,多思考和调试,最终解决问题,也能理解得更深刻。

③、代码可直接复制运行,如果对你有帮助,记得点个赞哦,也是对作者最大的鼓励,不足之处可以在评论区多多指正、交流。

作者:远方的星 CSDN:https://blog.csdn.net/qq_44921056

本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 环境
  • 网页分析
  • 爬虫代码实现及说明
相关产品与服务
语音合成
语音合成(Text To Speech,TTS)满足将文本转化成拟人化语音的需求,打通人机交互闭环。提供多场景、多语言的音色选择,支持 SSML 标记语言,支持自定义音量、语速等参数,让发音更专业、更符合场景需求。语音合成广泛适用于智能客服、有声阅读、新闻播报、人机交互等业务场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档