带有 JSON 数据的 UnicodeEncodeError

UnicodeEncodeError with JSON data

我有一个 JSON 对象,其中包含 UTF8 字符。当我尝试将对象打印到控制台时(在 Windows 8.1 中),它会抛出此错误:UnicodeEncodeError: 'charmap' codec can't encode character '\u2026' in position 3706: character maps to <undefined> 因为控制台不支持某些 UTF8 字符的显示。我检查了 this answer 但没有一个解决方案有效,因为无法对 JSON 对象进行编码和解码。如何解决 JSON 的编码问题?

def getTweets(self, company):
    #params
    baseUrl = 'https://api.twitter.com/1.1/search/tweets.json'
    values = {'q' : company, 'result_type' : 'recent', 'count' : 100}
    params = urllib.parse.urlencode(values)
    url = baseUrl + '?' + params
    #headers
    authorization = 'Bearer %s' % self.bearer 
    acceptEncoding = 'gzip'
    headers = {'User-Agent' : self.userAgent, 'Authorization' : authorization, 'Accept-Encoding' : acceptEncoding}
    req = urllib.request.Request(url, None, headers)
    response = urllib.request.urlopen(req)
    rawData = response.read()
    decompressedData = zlib.decompress(rawData, 16+zlib.MAX_WBITS)      
    decompressedData = decompressedData.decode('utf-8')
    #print(decompressedData)
    jsonData = json.loads(decompressedData)
    print(jsonData)

你说你的主机不支持UTF-8。所以你需要使用另一种编码。 我将尝试解释编码、解码和打印如何协同工作,从而导致您的异常;使用 decode(encoding) 可以将字节字符串转换为 unique unicode 表示形式。您指定编码是因为没有它,一个字节几乎可以映射到任何字符。您需要知道从网站获得的数据的编码,尽管它通常是 UTF-8。

当您从应用程序外部获取文本时,第一步是获取唯一的 unicode 表示,这样您就无需记住应用程序中每个文本的编码。

当使用 print 语句打印 unicode 时,它​​假定您使用标准编码,尽管您可以指定不同的标准编码。 该错误意味着 print 尝试在您的 unicode 文本上使用标准编码但失败了,因为它无法将超出其定义范围的字符编码为字节表示形式。

标准编码为:

print sys.stdout.encoding

当将文本从您的应用程序提供给另一个应用程序时,或者当您想要存储文本时,您需要将其编码为字节表示形式。因此,当您将 unicode 字符串提供给控制台时,您需要将其转换为具有预期编码的字节表示形式。对于控制台,我猜它希望来自您的应用程序的字节采用标准编码。

因此,要打印 unicode 字符串,您可以对 unicode 字符串使用编码,将其转换为您的控制台可以处理的字节表示形式。例如,您可以将它们转换为 ascii 字节表示形式,并将 ascii 定义范围之外的字符替换为问号:

# bytes to unicode
decompressedData_unicode = decompressedData.decode('utf-8')
# unicode to bytes
decompressedData_string = decompressedData_unicode.encode('ascii', 'replace')
# hope that the consoles standard encoding is compatible with ascii
print decompressedData_string

如果控制台允许其他编码,您可以将其设置为标准编码并直接打印unicode字符串,或者执行:

decompressedData_string = decompressedData_unicode.encode('standard encoding', 'replace')
print decompressedData_string

希望标准编码能够代表decompressedData_unicode中的每一个unicode字符。