【问题标题】:Opening UTF16 URL with urllib in Python [duplicate]在 Python 中使用 urllib 打开 UTF16 URL [重复]
【发布时间】:2013-05-13 12:42:50
【问题描述】:

我正在尝试使用 Google Translate API 将卡纳达语(因此编码为 utf-16)的文本翻译成英语。手动输入我的 URL,在插入我的 google api 密钥 https://www.googleapis.com/language/translate/v2?key=key#&q=ಚಿಂಚೋಳಿ&source=kn&target=en 后,我可以得到我想要的翻译。

然而,问题是这个 url 是 utf16 编码的。当我尝试使用 urllib 打开 url 时,我从下面收到错误消息。任何有关如何进行或其他方法的建议将不胜感激。

编辑: 我相信这个问题可以通过调用 urllib.parse.quote_plus(text) 来解决,其中 text 是 utf16 文本,并用该函数的返回值替换 utf16 文本。

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    urllib.request.urlopen(url)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 156, in urlopen
    return opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 469, in open
    response = self._open(req, data)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 487, in _open
    '_open', req)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 447, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 1283, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 1248, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/client.py", line 1061, in request
    self._send_request(method, url, body, headers)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/client.py", line 1089, in _send_request
    self.putrequest(method, url, **skips)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/http/client.py", line 953, in putrequest
    self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 73-79: ordinal not in range(128)

【问题讨论】:

  • 您能否在原始问题中包含print(repr(url)) 的输出?
  • quote_plus 或 quote 对我来说似乎是一种选择。
  • how this answer constructs an url from Unicode input,即当你将输入字节解码为Unicode时,只使用一次utf-16,之后输入编码是什么都没有关系。

标签: python python-3.x unicode urllib google-translate


【解决方案1】:

但是,问题是这个 url 是 utf16 编码的

UTF-16 并不像您认为的那样。它是将 Unicode 字符编码为某些系统(例如 Win32 API)的字符串类型内部使用的字节。 UTF-16 几乎从不在网络上使用,因为它不兼容 ASCII。

https://www.googleapis.com/language/translate/v2?key=key#&q=ಚಿಂಚೋಳಿ&source=kn&target=en

这不是一个 URI - URI 可能只包含 ASCII 字符。它是一个IRI可以包含其他 Unicode 字符。

但是urllib 不支持 IRI。有一些 Python 库直接支持 IRI;或者,您可以将任何 IRI 转换为 urllib 会满意的相应 URI。这是通过使用 IDNA 算法对主机名中的任何非 ASCII 字符进行编码,并在地址的其他部分(包括查询参数)中使用 URL 编码对字符的 UTF-8 表示进行编码来完成的.这给了你这个:

https://www.googleapis.com/language/translate/v2?key=key#&q=%E0%B2%9A%E0%B2%BF%E0%B2%82%E0%B2%9A%E0%B3%8B%E0%B2%B3%E0%B2%BF&source=kn&target=en

但是,这里使用# 看起来不正确 - 这是一种用于从浏览器传递数据的客户端机制,不适用于服务器请求。

通常你会做这样的事情:

baseurl= 'https://www.googleapis.com/language/translate/v2'
text= u'ಚಿಂಚೋಳಿ'
url= baseurl+'?'+urllib.urlencode(dict(
    source= 'kn', target= 'en',
    q= text.encode('utf-8'),
    key= key
))

【讨论】:

  • 没有必要在 Python 3.3 中编码 Unicode 字符串 urlencode({'q':u'ಚಿಂಚೋಳಿ'}) 工作得很好。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2020-10-01
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
相关资源
最近更新 更多