Python 使用 Unicode 参数的请求 URL
Python Requests URL with Unicode Parameters
我目前正在尝试使用请求库在 python 中使用日语字符和短语点击 google tts url、http://translate.google.com/translate_tts。
这是一个例子:
http://translate.google.com/translate_tts?tl=ja&q=ひとつ
但是,当我尝试使用 python 请求库下载端点 returns 的 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
此外,如果我在此代码段中打印 text
或 url
,则 kana/kanji 会在我的控制台中正确呈现。
编辑:
如果我尝试对 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
哪个returns这个:
http://translate.google.com/translate_tts?tl=ja&q=%E3%81%B2%E3%81%A8%E3%81%A4
这似乎应该有效,但实际上无效。
编辑 2:
如果我尝试使用 urlllb/urllib2,我会收到 403 错误。
编辑 3:
所以,看来这个problem/behavior只是单纯局限于这个端点。如果我尝试以下 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编码。我在将 cyrllic 和 CJK 语言打印到 csvs 时遇到问题,这成功了。
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.
给出了一个稍长的答案
将 User-Agent 设置为 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
用户代理可能是问题的一部分,但在本例中并非如此。 translate_tts
服务拒绝(使用 HTTP 403)某些用户代理,例如任何以 Python
、curl
、wget
和其他可能开头的内容。这就是为什么您在使用 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",尽管为平假名输入产生的音频与其他音频略有不同。
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)
我目前正在尝试使用请求库在 python 中使用日语字符和短语点击 google tts url、http://translate.google.com/translate_tts。
这是一个例子:
http://translate.google.com/translate_tts?tl=ja&q=ひとつ
但是,当我尝试使用 python 请求库下载端点 returns 的 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
此外,如果我在此代码段中打印 text
或 url
,则 kana/kanji 会在我的控制台中正确呈现。
编辑:
如果我尝试对 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
哪个returns这个:
http://translate.google.com/translate_tts?tl=ja&q=%E3%81%B2%E3%81%A8%E3%81%A4
这似乎应该有效,但实际上无效。
编辑 2:
如果我尝试使用 urlllb/urllib2,我会收到 403 错误。
编辑 3:
所以,看来这个problem/behavior只是单纯局限于这个端点。如果我尝试以下 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编码。我在将 cyrllic 和 CJK 语言打印到 csvs 时遇到问题,这成功了。
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.
给出了一个稍长的答案将 User-Agent 设置为 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
用户代理可能是问题的一部分,但在本例中并非如此。 translate_tts
服务拒绝(使用 HTTP 403)某些用户代理,例如任何以 Python
、curl
、wget
和其他可能开头的内容。这就是为什么您在使用 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",尽管为平假名输入产生的音频与其他音频略有不同。
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)