daijunhao 发表于 2024-3-5 20:26:58

[非mc]Python手搓全球发音

本帖最后由 daijunhao 于 2024-3-6 17:43 编辑

# 前言
最近全球发音这东西挺搞笑的(gee)
但是网易有道词典中的全球发音要下载客户端才有


客户端要200多MB

那不妨来试试python弄出来的全球发音吧(用的是网易有道词典的api,应该算吧)
# 原理分析
首先是有道词典获取全球发音的内容
https://dict.youdao.com/mvoice?method=getInfo&word=gee
"gee"是一个单词
访问之后我们就能看到json
{
    "attributes": {
      "total": 4,
      "headword": "gee",
      "source_zh": "英语",
      "source": "English",
      "langNumber": 3
    },
    "items": [
      {
            "headword": "gee",
            "voices": [
                {
                  "country": "China",
                  "voiceId": 1762315453293305900,
                  "voiceId_str": "1762315453293305856",
                  "sex": "m",
                  "location": "",
                  "votes": 83643,
                  "oppose": 2076,
                  "id": 1709003841851,
                  "country_zh": "中国"
                },
                {
                  "country": "United Kingdom",
                  "voiceId": 719288437215584000,
                  "voiceId_str": "719288437215583939",
                  "sex": "m",
                  "location": "55.378051,-3.435973",
                  "votes": 2282,
                  "oppose": 1629,
                  "id": 767804,
                  "country_zh": "英国"
                }
            ],
            "lang-zh": "英语",
            "lang": "English"
      },
      {
            "headword": "gee",
            "voices": [
                {
                  "country": "South Africa",
                  "voiceId": 419445984134648960,
                  "voiceId_str": "419445984134648974",
                  "sex": "m",
                  "location": "-30.559482,22.937506",
                  "votes": 444,
                  "oppose": 775,
                  "id": 2666578,
                  "country_zh": "南非"
                }
            ],
            "lang-zh": "南非语",
            "lang": "Afrikaans"
      },
      {
            "headword": "gee",
            "voices": [
                {
                  "country": "United Kingdom",
                  "voiceId": 155786722392261400,
                  "voiceId_str": "155786722392261414",
                  "sex": "m",
                  "location": "55.378051,-3.435973",
                  "votes": 403,
                  "oppose": 514,
                  "id": 5731589,
                  "country_zh": "英国"
                }
            ],
            "lang-zh": "马恩岛语",
            "lang": "Manx"
      }
    ]
}在这json里面
"sex"这个值中代表的是发声性别
比如里面的值是"m"就代表是男性发声
里面的值是"f"就代表是女性发声
"country"为国家,就是发音人所在的国家
"votes"为投票数
其中里面的"voiceId_str"这个值就是发音的关键了
然后我们再获取音频内容
https://dict.youdao.com/mvoice?method=getVoice&id=1762315453293305856
其中"1762315453293305856"就是我们获取到的"voiceId_str"
访问这段内容,就可以看到音频了


然后就是有道词典的英式发音和美式发音

先是英式发音
https://dict.youdao.com/dictvoice?audio=gee&type=1
其中这里面的"gee"为单词
访问这段内容,就可以听到英式发音


然后是美式发音
https://dict.youdao.com/dictvoice?audio=gee&type=2
其中这里面的"gee"为单词
访问这段内容,就可以听到美式发音


# 代码实现
使用python(需要安装wxpython requests io soundfile sounddevice库)
# -*- coding:utf-8 -*-
import wx
import requests
import json
from io import BytesIO
import sounddevice as sd
import soundfile as sf
#忽略证书警告
requests.packages.urllib3.disable_warnings()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0'
}
class Frame(wx.Frame):
    def __init__(self):
      wx.Frame.__init__(self, None, title='全球发音--网易有道词典 by:daijunhao', size=(1200, 800),name='frame',style=541072384)
      self.启动窗口 = wx.Panel(self)
      self.Centre()
      self.超级列表框1 = wx.ListCtrl(self.启动窗口, size=(1109, 380), pos=(25, 28), name='listCtrl', style=8227)
      self.超级列表框1.AppendColumn('序号', 0, 154)
      self.超级列表框1.AppendColumn('发音单词', 0, 109)
      self.超级列表框1.AppendColumn('发音语言', 0, 151)
      self.超级列表框1.AppendColumn('投票数', 0, 171)
      self.超级列表框1.AppendColumn('音频id', 0, 490)
      self.超级列表框1.Bind(wx.EVT_LIST_ITEM_SELECTED,self.超级列表框1_选中表项)
      self.编辑框1 = wx.TextCtrl(self.启动窗口, size=(336, 22), pos=(117, 438), value='', name='text', style=0)
      self.标签1 = wx.StaticText(self.启动窗口, size=(80, 24), pos=(25, 437), label='请输入单词:', name='staticText',style=2321)
      self.按钮1 = wx.Button(self.启动窗口, size=(80, 32), pos=(25, 474), label='查询单词', name='button')
      self.按钮1.Bind(wx.EVT_BUTTON, self.按钮1_按钮被单击)
      self.按钮2 = wx.Button(self.启动窗口, size=(171, 81), pos=(20, 667), label='下载音频(全球发音)', name='button')
      self.按钮2.Bind(wx.EVT_BUTTON, self.按钮2_按钮被单击)
      self.按钮3 = wx.Button(self.启动窗口, size=(171, 81), pos=(20, 571), label='音频朗读(全球发音)', name='button')
      self.按钮3.Bind(wx.EVT_BUTTON, self.按钮3_按钮被单击)
      self.按钮4 = wx.Button(self.启动窗口, size=(80, 32), pos=(1054, 416), label='刷新', name='button')
      self.按钮4.Bind(wx.EVT_BUTTON, self.按钮4_按钮被单击)
      self.按钮5 = wx.Button(self.启动窗口, size=(171, 81), pos=(410, 667), label='英式发音', name='button')
      self.按钮5.Bind(wx.EVT_BUTTON, self.按钮5_按钮被单击)
      self.按钮6 = wx.Button(self.启动窗口, size=(171, 81), pos=(410, 571), label='美式发音', name='button')
      self.按钮6.Bind(wx.EVT_BUTTON, self.按钮6_按钮被单击)
      self.按钮7 = wx.Button(self.启动窗口, size=(171, 81), pos=(214, 571), label='下载美式发音', name='button')
      self.按钮7.Bind(wx.EVT_BUTTON, self.按钮7_按钮被单击)
      self.按钮8 = wx.Button(self.启动窗口, size=(171, 81), pos=(214, 667), label='下载英式发音', name='button')
      self.按钮8.Bind(wx.EVT_BUTTON, self.按钮8_按钮被单击)
      self.按钮2.Hide()
      self.按钮3.Hide()

      self.按钮8.Hide()
      self.按钮7.Hide()
      self.按钮6.Hide()
      self.按钮5.Hide()


    def 超级列表框1_选中表项(self,event):
      self.按钮2.Enable()
      self.按钮3.Enable()


    def 按钮1_按钮被单击(self,event):
      self.按钮8.Show()
      self.按钮7.Show()
      self.按钮6.Show()
      self.按钮5.Show()
      mvoice_get_list = json.loads(requests.get(f"https://dict.youdao.com/mvoice?method=getInfo&word={str(self.编辑框1.GetValue())}",headers=headers,verify=False).text)
      self.超级列表框1.ClearAll()
      self.按钮2.Disable()
      self.按钮3.Disable()
      self.超级列表框1.AppendColumn('序号', 0, 154)
      self.超级列表框1.AppendColumn('发音单词', 0, 109)
      self.超级列表框1.AppendColumn('发音语言', 0, 151)
      self.超级列表框1.AppendColumn('投票数', 0, 171)
      self.超级列表框1.AppendColumn('音频id', 0, 490)
      voice_count = 1
      try:
            self.按钮2.Show()
            self.按钮3.Show()
            for item in mvoice_get_list['items']:
                for mvoice_get_list1 in item['voices']:
                  if str(mvoice_get_list1["sex"]) == "f":
                        self.超级列表框1.Append(}/女', f'{str(mvoice_get_list["attributes"]["headword"])}', f'{str(item["lang-zh"])}', f'{str(mvoice_get_list1["votes"])}', f'{str(mvoice_get_list1["voiceId_str"])}'])
                  if str(mvoice_get_list1["sex"]) == "m":
                        self.超级列表框1.Append(}/男', f'{str(mvoice_get_list["attributes"]["headword"])}', f'{str(item["lang-zh"])}', f'{str(mvoice_get_list1["votes"])}', f'{str(mvoice_get_list1["voiceId_str"])}'])
                  voice_count += 1
            voice_info = wx.MessageDialog(None, caption="info",message=f"获取完毕,该单词有{str(voice_count-1)}位用户贡献了发音",style=wx.OK | wx.ICON_INFORMATION)
            if voice_info.ShowModal() == wx.ID_OK:
                pass
      except Exception:
            self.按钮2.Disable()
            self.按钮3.Disable()
            self.按钮2.Hide()
            self.按钮3.Hide()

            self.按钮8.Hide()
            self.按钮7.Hide()
            self.按钮6.Hide()
            self.按钮5.Hide()
            voice_error = wx.MessageDialog(None, caption="Error",message="获取失败,请检查你的单词是否有用户贡献发音",style=wx.OK | wx.ICON_ERROR)
            if voice_error.ShowModal() == wx.ID_OK:
                pass


    def 按钮3_按钮被单击(self,event):
      try:
            mvoice_get_list = json.loads(requests.get(f"https://dict.youdao.com/mvoice?method=getInfo&word={str(self.编辑框1.GetValue())}",headers=headers,verify=False).text)
            voice_count = 1
            for item in mvoice_get_list['items']:
                for mvoice_get_list1 in item['voices']:
                  if voice_count == self.超级列表框1.GetFirstSelected()+1:
                        mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/mvoice?method=getVoice&id={str(mvoice_get_list1['voiceId_str'])}",headers=headers,verify=False).content
                        filename = BytesIO(mvoice_get_mp3)
                        # Extract data and sampling rate from file
                        data, fs = sf.read(filename, dtype='float32')
                        sd.play(data, fs)
                        status = sd.wait()# Wait until file is done playing
                  voice_count += 1
            voice_playsound_info = wx.MessageDialog(None, caption="info", message="朗读完毕",style=wx.OK | wx.ICON_INFORMATION)
            if voice_playsound_info.ShowModal() == wx.ID_OK:
                pass
      except Exception:
            voice_playsound_error = wx.MessageDialog(None, caption="Error", message="朗读失败,请检查你输入的单词是否为空", style=wx.OK | wx.ICON_ERROR)
            if voice_playsound_error.ShowModal() == wx.ID_OK:
                pass


    def 按钮2_按钮被单击(self,event):
      try:
            mvoice_get_list = json.loads(requests.get(f"https://dict.youdao.com/mvoice?method=getInfo&word={str(self.编辑框1.GetValue())}",headers=headers,verify=False).text)
            voice_count = 1
            for item in mvoice_get_list['items']:
                for mvoice_get_list1 in item['voices']:
                  if voice_count == self.超级列表框1.GetFirstSelected()+1:
                        mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/mvoice?method=getVoice&id={str(mvoice_get_list1['voiceId_str'])}",headers=headers,verify=False).content
                  voice_count += 1
            fileFilter = "mp3 Files (*.mp3)|*.mp3|" "All files (*.*)|*.*"
            fileDialog = wx.FileDialog(self, message="保存此mp3文件", wildcard=fileFilter, style=wx.FD_SAVE)
            dialogResult = fileDialog.ShowModal()
            if dialogResult == wx.ID_OK:
                with open(f"{fileDialog.GetPath()}",mode="wb") as f:
                  f.write(mvoice_get_mp3)
                  f.close()
                voice_save_ok = wx.MessageDialog(None, caption="info", message="保存成功",style=wx.OK | wx.ICON_INFORMATION)
                if voice_save_ok.ShowModal() == wx.ID_OK:
                  pass
      except Exception:
            voice_save_error = wx.MessageDialog(None, caption="Error", message="保存失败,请检查你输入的单词是否为空", style=wx.OK | wx.ICON_ERROR)
            if voice_save_error.ShowModal() == wx.ID_OK:
                pass


    def 按钮4_按钮被单击(self, event):
            mvoice_get_list = json.loads(requests.get(f"https://dict.youdao.com/mvoice?method=getInfo&word={str(self.编辑框1.GetValue())}",headers=headers,verify=False).text)
            self.超级列表框1.ClearAll()
            self.按钮2.Disable()
            self.按钮3.Disable()
            self.超级列表框1.AppendColumn('序号', 0, 154)
            self.超级列表框1.AppendColumn('发音单词', 0, 109)
            self.超级列表框1.AppendColumn('发音语言', 0, 151)
            self.超级列表框1.AppendColumn('投票数', 0, 171)
            self.超级列表框1.AppendColumn('音频id', 0, 490)
            voice_count = 1
            try:
                self.按钮2.Show()
                self.按钮3.Show()
                for item in mvoice_get_list['items']:
                  for mvoice_get_list1 in item['voices']:
                        if str(mvoice_get_list1["sex"]) == "f":
                            self.超级列表框1.Append(}/女', f'{str(mvoice_get_list["attributes"]["headword"])}', f'{str(item["lang-zh"])}', f'{str(mvoice_get_list1["votes"])}', f'{str(mvoice_get_list1["voiceId_str"])}'])
                        if str(mvoice_get_list1["sex"]) == "m":
                            self.超级列表框1.Append(}/男', f'{str(mvoice_get_list["attributes"]["headword"])}', f'{str(item["lang-zh"])}', f'{str(mvoice_get_list1["votes"])}', f'{str(mvoice_get_list1["voiceId_str"])}'])
                        voice_count += 1
                voice_info = wx.MessageDialog(None, caption="info",message=f"获取完毕,该单词有{str(voice_count-1)}位用户贡献了发音",style=wx.OK | wx.ICON_INFORMATION)
                if voice_info.ShowModal() == wx.ID_OK:
                  pass
            except Exception:
                self.按钮2.Disable()
                self.按钮3.Disable()
                self.按钮2.Hide()
                self.按钮3.Hide()
                voice_error = wx.MessageDialog(None, caption="Error",message="获取失败,请检查你的单词是否有用户贡献发音",style=wx.OK | wx.ICON_ERROR)
                if voice_error.ShowModal() == wx.ID_OK:
                  pass

    def 按钮5_按钮被单击(self, event):
      try:
            mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/dictvoice?audio={str(self.编辑框1.GetValue())}&type=1",headers=headers,verify=False).content
            filename = BytesIO(mvoice_get_mp3)
            # Extract data and sampling rate from file
            data, fs = sf.read(filename, dtype='float32')
            sd.play(data, fs)
            status = sd.wait()# Wait until file is done playing
            voice_playsound_info = wx.MessageDialog(None, caption="info", message="朗读完毕",style=wx.OK | wx.ICON_INFORMATION)
            if voice_playsound_info.ShowModal() == wx.ID_OK:
                pass
      except Exception:
            voice_playsound_error = wx.MessageDialog(None, caption="Error", message="朗读失败,请检查你输入的单词是否为空", style=wx.OK | wx.ICON_ERROR)
            if voice_playsound_error.ShowModal() == wx.ID_OK:
                pass

    def 按钮6_按钮被单击(self, event):
      try:
            mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/dictvoice?audio={str(self.编辑框1.GetValue())}&type=2",headers=headers,verify=False).content
            filename = BytesIO(mvoice_get_mp3)
            # Extract data and sampling rate from file
            data, fs = sf.read(filename, dtype='float32')
            sd.play(data, fs)
            status = sd.wait()# Wait until file is done playing
            voice_playsound_info = wx.MessageDialog(None, caption="info", message="朗读完毕",style=wx.OK | wx.ICON_INFORMATION)
            if voice_playsound_info.ShowModal() == wx.ID_OK:
                pass
      except Exception:
            voice_playsound_error = wx.MessageDialog(None, caption="Error", message="朗读失败,请检查你输入的单词是否为空", style=wx.OK | wx.ICON_ERROR)
            if voice_playsound_error.ShowModal() == wx.ID_OK:
                pass

    def 按钮7_按钮被单击(self, event):
      mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/dictvoice?audio={str(self.编辑框1.GetValue())}&type=2",headers=headers,verify=False).content
      fileFilter = "mp3 Files (*.mp3)|*.mp3|" "All files (*.*)|*.*"
      fileDialog = wx.FileDialog(self, message="保存此mp3文件", wildcard=fileFilter, style=wx.FD_SAVE)
      dialogResult = fileDialog.ShowModal()
      if dialogResult == wx.ID_OK:
            with open(f"{fileDialog.GetPath()}",mode="wb") as f:
                f.write(mvoice_get_mp3)
                f.close()
            voice_save_ok = wx.MessageDialog(None, caption="info", message="保存成功",style=wx.OK | wx.ICON_INFORMATION)
            if voice_save_ok.ShowModal() == wx.ID_OK:
                pass

    def 按钮8_按钮被单击(self, event):
      mvoice_get_mp3 = requests.get(f"https://dict.youdao.com/dictvoice?audio={str(self.编辑框1.GetValue())}&type=1",headers=headers,verify=False).content
      fileFilter = "mp3 Files (*.mp3)|*.mp3|" "All files (*.*)|*.*"
      fileDialog = wx.FileDialog(self, message="保存此mp3文件", wildcard=fileFilter, style=wx.FD_SAVE)
      dialogResult = fileDialog.ShowModal()
      if dialogResult == wx.ID_OK:
            with open(f"{fileDialog.GetPath()}",mode="wb") as f:
                f.write(mvoice_get_mp3)
                f.close()
            voice_save_ok = wx.MessageDialog(None, caption="info", message="保存成功",style=wx.OK | wx.ICON_INFORMATION)
            if voice_save_ok.ShowModal() == wx.ID_OK:
                pass

class myApp(wx.App):
    def OnInit(self):
      self.frame = Frame()
      self.frame.Show(True)
      return True

if __name__ == '__main__':
    app = myApp()
    app.MainLoop()图形化界面:

下载链接:https://wwz.lanzouo.com/i1TXr1qipxla密码:2da5






limil_23 发表于 2024-3-5 20:35:33

瓦 好力害啊 python难吗

jia123444 发表于 2024-3-5 22:16:04

程序很好,但是被“网易”劝退

daijunhao 发表于 2024-3-6 17:22:12

本帖最后由 daijunhao 于 2024-3-6 17:40 编辑

话说回来(草稿这东西还会自动发出去,下次直接粘贴到word文档里了)

daijunhao 发表于 2024-3-6 17:30:28

limil_23 发表于 2024-3-5 20:35
瓦 好力害啊 python难吗

只有单独命令提示符还可以,图形化界面的话...

mouranj 发表于 2024-3-8 23:07:45

大佬nb 搞得我都想学Python了((

highlandbur 发表于 2024-4-24 18:58:17

6666666666666666
页: [1]
查看完整版本: [非mc]Python手搓全球发音