【问题标题】:Send a non-ASCII POST request in Python?在 Python 中发送非 ASCII POST 请求?
【发布时间】:2012-01-07 23:33:49
【问题描述】:

我正在尝试向网络应用发送 POST 请求。我正在使用 mechanize 模块(本身是 urllib2 的包装器)。无论如何,当我尝试发送 POST 请求时,我得到UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)。我尝试放置unicode(string)unicode(string, encoding="utf-8")unicode(string).encode() 等,但没有任何效果 - 要么返回上述错误,要么返回 TypeError: decoding Unicode is not supported

我查看了类似问题的其他 SO 答案,但没有任何帮助。

提前致谢!

EDIT:产生错误的示例:

prda = "šđćč" #valid UTF-8 characters
prda # typing in python shell 
'\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d'
print prda # in shell
šđćč
prda.encode("utf-8") #in shell
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)
unicode(prda)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)

【问题讨论】:

  • 如果您展示一个产生错误的小型、独立的示例,我会提供帮助。
  • @ekhumoro 添加了示例,希望它能清除它

标签: python html http post unicode


【解决方案1】:

我假设您使用的是 Python 2.x。

给定一个 unicode 对象:

myUnicode = u'\u4f60\u597d'

使用 utf-8 编码:

mystr = myUnicode.encode('utf-8')

请注意,您需要明确指定编码。默认情况下(通常)使用 ascii。

【讨论】:

  • 感谢您的回复。如果我有一个字符串变量(而不是字符串),我将如何将其转换为 unicode 对象?在分配字符串变量之前,我只需在代码中添加u' 前缀。
【解决方案2】:

在您的示例中,您使用包含非 ascii 字符的非 unicode 字符串文字,这导致 prda 成为 bytes 字符串。

为了实现这一点,python 使用sys.stdin.encoding 自动对字符串进行编码。在您的情况下,这意味着字符串被编码为“utf-8”。

要将prda 转换为unicode 对象,您需要使用适当的编码对其进行解码:

>>> print prda.decode('utf-8')
šđćč

请注意,在脚本或模块中,您不能依赖 python 来自动猜测编码 - 您需要在文件顶部显式地删除编码,如下所示:

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

每当您在 Python 2 中遇到 unicode 错误时,通常是因为您的代码将字节字符串与 unicode 字符串混合在一起。因此,您应该始终使用type(string) 来检查导致错误的字符串类型。

如果字符串对象是<type 'str'>,但你需要unicode,解码它使用适当的编码。如果字符串对象是<type 'unicode'>,但您需要字节,请使用适当的编码对其进行编码

【讨论】:

    【解决方案3】:

    您不需要在unicode 调用中包装您的字符,因为它们已经被编码:) 如果有的话,您需要DE-对其进行编码以获得一个 unicode 对象:

    >>> s = '\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d'   # your string
    >>> s.decode('utf-8')
    u'\u0161\u0111\u0107\u010d'
    >>> type(s.decode('utf-8'))
    <type 'unicode'>
    

    我不知道mechanize,所以我不知道它是否正确处理它,恐怕。

    我对常规的urllib2 POST 调用的做法是使用urlencode

    >>> from urllib import urlencode
    >>> postData = urlencode({'test': s })   # note I'm NOT decoding it
    >>> postData
    'test=%C5%A1%C4%91%C4%87%C4%8D'
    >>> urllib2.urlopen(url, postData)   # etc etc etc
    

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 1970-01-01
      • 2021-11-26
      • 2013-11-15
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多