Python使用Unicode参数请求URL

我目前正尝试使用请求库在
python中使用日语字符和短语来搜索google tts url,
http://translate.google.com/translate_tts.

这是一个例子:

http://translate.google.com/translate_tts?tl=ja&q =ひとつ

但是,当我尝试使用python请求库下载端点返回的mp3时,生成的mp3为空.我已经验证我可以在使用非unicode字符(通过romanji)的请求中点击此URL并获得正确的响应.

这是我用来发出请求的代码的一部分

langs = {'japanese': 'ja',
         'english': 'en'}

def get_sound_file_for_text(text, download=False, lang='japanese'):

    r = StringIO()
    glang = langs[lang]
    text = text.replace('*', '')
    text = text.replace('/', '')
    text = text.replace('x', '')
    url = 'http://translate.google.com/translate_tts'
    if download:
        result = requests.get(url, params={'tl': glang, 'q': text})
        r.write(result.content)
        r.seek(0)
        return r
    else:
        return url

此外,如果我在此片段中打印textor url,则在我的控制台中正确呈现假名/汉字.

编辑:

如果我尝试对unicode进行编码并引用它,我仍会得到相同的响应.

# -*- coding: utf-8 -*-

from StringIO import StringIO
import urllib
import requests

__author__ = 'jacob'

langs = {'japanese': 'ja',
         'english': 'en'}

def get_sound_file_for_text(text, download=False, lang='japanese'):

    r = StringIO()
    glang = langs[lang]
    text = text.replace('*', '')
    text = text.replace('/', '')
    text = text.replace('x', '')
    text = urllib.quote(text.encode('utf-8'))
    url = 'http://translate.google.com/translate_tts?tl=%(glang)s&q=%(text)s' % locals()
    print url
    if download:
        result = requests.get(url)
        r.write(result.content)
        r.seek(0)
        return r
    else:
        return url

哪个返回:

http://translate.google.com/translate_tts?tl=ja&q=%E3%81%B2%E3%81%A8%E3%81%A4

这看起来应该有效,但事实并非如此.

编辑2:

如果我尝试使用urlllb / urllib2,我会收到403错误.

编辑3:

因此,似乎此问题/行为仅限于此端点.如果我尝试以下URL,则使用不同的端点.

http://www.kanjidamage.com/kanji/13-un-%E4%B8%8D

从请求和我的浏览器中,我得到相同的响应(它们匹配).如果我甚至尝试ascii字符到服务器,像这个网址.

http://translate.google.com/translate_tts?tl=ja&q=sayonara

我也得到相同的反应(他们再次匹配).但是如果我尝试将unicode字符发送到此URL,我会在浏览器上获得正确的音频文件,但不是来自发送音频文件但没有声音的请求.

http://translate.google.com/translate_tts?tl=ja&q=%E3%81%B2%E3%81%A8%E3%81%A4

那么,似乎这种行为仅限于Google TTL网址?

最佳答案 用户代理可以是问题的一部分,但是,在这种情况下不是. translate_tts服务拒绝(使用HTTP 403)一些用户代理,例如任何以Python,curl,wget和其他可能开头的东西.这就是为什么在使用urllib2.urlopen()时看到HTTP 403响应的原因 – 它将用户代理设置为Python-urllib / 2.7(版本可能会有所不同).

您发现将用户代理设置为Mozilla / 5.0可以解决问题,但这可能有效,因为API可能会假定基于用户代理的特定编码.

您实际应该做的是使用ie字段显式指定URL字符编码.您的网址请求应如下所示:

http://translate.google.com/translate_tts?ie=UTF-8&tl=ja&q=%E3%81%B2%E3%81%A8%E3%81%A4

注意ie = UTF-8明确设置URL字符编码.规范确实声明UTF-8是默认值,但似乎并不完全正确,因此您应该始终在请求中设置ie.

API支持汉字,平假名和片假名(可能还有其他?).这些URL都产生“nihongo”,尽管为平假名输入产生的音频与其他视频的变化略有不同.

import requests

one = u'\u3072\u3068\u3064'
kanji = u'\u65e5\u672c\u8a9e'
hiragana = u'\u306b\u307b\u3093\u3054'
katakana = u'\u30cb\u30db\u30f3\u30b4'
url = 'http://translate.google.com/translate_tts'

for text in one, kanji, hiragana, katakana:
    r = requests.get(url, params={'ie': 'UTF-8', 'tl': 'ja', 'q': text})
    print u"{} -> {}".format(text, r.url)
    open(u'/tmp/{}.mp3'.format(text), 'wb').write(r.content)
点赞