【问题标题】:Python Requests URL with Unicode ParametersPython 请求带有 Unicode 参数的 URL
【发布时间】:2015-03-13 09:44:56
【问题描述】:

我目前正在尝试使用 requests 库在 python 中使用日文字符和短语点击 google tts url http://translate.google.com/translate_tts

这是一个例子:

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

但是,当我尝试使用 python 请求库下载端点返回的 mp3 时,生成的 mp3 为空白。我已验证我可以使用非 Unicode 字符(通过罗马字)在请求中点击此 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

另外,如果我在这个 sn-p 中打印 texturl,假名/日本汉字会在我的控制台中正确呈现。

编辑:

如果我尝试对 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 字符发送到服务器,例如这个 url。

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

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

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

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

【问题讨论】:

  • 您的控制台可能未正确配置为显示字符,这听起来像是一般的 utf-8 编码问题。即使我很确定您使用的是 Windows 机器,我能否问一下您使用的是什么操作系统。
  • @AustinA 它在我的控制台上显示正常。它是 pycharm 中的一个控制台,我目前正在 linux 环境中运行它。
  • 嘿,对不起@jab,我把你的“渲染”误读为“没有渲染”。无论如何,我希望我添加的代码 sn-p 有效。我不确定你是否尝试过预先进行 UTF-8 编码和解码。
  • 另外注意,如果你尝试使用 なな。它将返回一个“e”音,如字符え。我尝试过的其他一切都没有返回。

标签: python unicode python-requests


【解决方案1】:

用户代理可能是问题的一部分,但在这种情况下并非如此。 translate_tts 服务拒绝(使用 HTTP 403)一些用户代理,例如任何以Pythoncurlwget 以及可能的其他开头的。这就是您在使用 urllib2.urlopen() 时看到 HTTP 403 响应的原因 - 它将用户代理设置为 Python-urllib/2.7(版本可能会有所不同)。

您发现将用户代理设置为 Mozilla/5.0 可以解决问题,但这可能会起作用,因为 API 可能会根据用户代理假定特定的编码。

您实际上应该做的是使用ie 字段明确指定URL 字符编码。您的 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”,尽管为平假名输入生成的音频与其他 URL 的曲调略有不同。

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)

【讨论】:

    【解决方案2】:

    我之前做了这个小方法来帮助我进行 UTF-8 编码。我在将西里尔文和 CJK 语言打印到 csv 时遇到了问题,这成功了。

    def assist(unicode_string):
        utf8 = unicode_string.encode('utf-8')
        read = utf8.decode('string_escape')
    
        return read   ## UTF-8 encoded string
    

    另外,请确保在 .py 的开头有这两行。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    

    第一行只是一个好的 python 习惯,它指定在 .py 上使用哪个编译器(只有在你的机器上加载了多个版本的 python 时才真正有用)。第二行指定 python 文件的编码。 here 给出了一个稍长的答案。

    【讨论】:

    • 我尝试将 unicode 编码为 utf-8,但我仍然得到相同的行为。 ://
    • 您是否尝试将输出写入文本文件?我很想听听结果。
    • 当我使用带有 utf-8 编码 URL 的请求库时,我得到一个空白的 mp3 文件(但那里有 mp3 详细信息)。如果我使用 urllib2/httplib2 传递相同的 URL,则会收到 403 错误。
    【解决方案3】:

    将用户代理设置为 Mozilla/5.0 可解决此问题。

    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', '')
        url = 'http://translate.google.com/translate_tts'
        if download:
            result = requests.get(url, params={'tl': glang, 'q': text}, headers={'User-Agent': 'Mozilla/5.0'})
            r.write(result.content)
            r.seek(0)
            return r
        else:
            return url
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 2012-04-10
      • 2017-02-22
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      • 2017-11-25
      • 2013-03-31
      相关资源
      最近更新 更多