【问题标题】:URLDecoding requestsURL 编码请求
【发布时间】:2015-12-27 04:44:04
【问题描述】:

我正在尝试从requests 获取原始网址。这是我目前所拥有的:

res = requests.get(...)
url = urllib.unquote(res.url).decode('utf8') 

然后我收到一条错误消息:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 60-61: ordinal not in range(128)

我请求的原始网址是:

https://www.microsoft.com/de-at/store/movies/american-pie-pr\xc3\xa4sentiert-nackte-tatsachen/8d6kgwzl63ql

当我尝试打印时会发生以下情况:

>>> print '111', res.url
111 https://www.microsoft.com/de-at/store/movies/american-pie-pr%C3%A4sentiert-nackte-tatsachen/8d6kgwzl63ql
>>> print '222', urllib.unquote( res.url )
222 https://www.microsoft.com/de-at/store/movies/american-pie-präsentiert-nackte-tatsachen/8d6kgwzl63ql
>>> print '333', urllib.unquote(res.url).decode('utf8') 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 60-61: ordinal not in range(128)

为什么会发生这种情况,我该如何解决?

【问题讨论】:

标签: python unicode python-requests urlencode


【解决方案1】:
UnicodeEncodeError: 'ascii' codec can't encode characters

您正在尝试解码一个已经是 Unicode 的字符串。它在 Python 3 上引发 AttributeError(unicode 字符串没有 .decode() 方法)。 Python 2 尝试先使用sys.getdefaultencoding() ('ascii') 将字符串编码为字节,然后再将其传递给.decode('utf8'),从而导致UnicodeEncodeError

简而言之,不要在 Unicode 字符串上调用 .decode(),而是使用它:

print urllib.unquote(res.url.encode('ascii')).decode('utf-8')

没有.decode() 调用,如果您的环境使用的字符编码不是utf-8,代码会打印可能导致mojibake 的字节(假设一个字节串被传递给unquote())。为避免 mojibake,始终打印 Unicode(不要将 text 打印为字节),不要在脚本中硬编码环境的字符编码,即 .decode() 是必需的在这里。


There is a bug in urllib.unquote() if you pass it a Unicode string:

>>> print urllib.unquote(u'​%C3%A4')
ä
>>> print urllib.unquote('​%C3%A4') # utf-8 output
ä

在 Python 2 上将字节串传递给 unquote()

【讨论】:

  • type(urllib.unquote("https://www.microsoft.com/de-at/store/movies/american-pie-pr%C3%A4sentiert-nackte-tatsachen/8d6kgwzl63ql")) == <type 'str'>。我认为问题在于他的语言环境
  • 没关系。 OP 没有从 urllib.unquote( res.url ) 得到异常,如果我使用 Unicode,我也没有得到异常:urllib.unquote(u"https://www.microsoft.com/de-at/store/movies/american-pie-‌​pr%C3%A4sentiert-nackte-tatsachen/8d6kgwzl63ql")
  • @AlastairMcCormack:这里有 3 个单独的问题。解决所有 3 个问题的解决方案是 .encode(),然后是 .decode(),如答案所示。 type(res.url) 是问题中的 unicode,否则我们不会看到 UnicodeEncodeErrorurllib.unquote() is broken for unicode urls
  • 对不起,你是对的。我弄错了棍子的一端:)
  • @AlastairMcCormack:不要为此道歉,我很感谢您的反馈。每个人都会犯错,here's my recent brain failure.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 2018-05-31
  • 1970-01-01
相关资源
最近更新 更多