Unicode API 响应引发错误 ascii' 编解码器无法在位置 22462' 中编码字符 u'\u2019'



我正在做一个API调用,并且响应具有Unicode字符。将此响应加载到文件中会引发以下错误:

'ascii' codec can't encode character u'u2019' in position 22462

我尝试了解码和编码的所有组合('utf-8')。

这是代码:

url = "https://%s?start_time=%s&include=metric_sets,users,organizations,groups" % (api_path, start_epoch)
while url != None and url != "null" :
json_filename = "%s/%s.json" % (inbound_folder, start_epoch)
try:
    resp = requests.get(url,
                        auth=(api_user, api_pwd),
                        headers={'Content-Type': 'application/json'})
except requests.exceptions.RequestException as e:
    print "|********************************************************|"
    print e
    return "Error: {}".format(e)
    print "|********************************************************|"
    sys.exit(1)
try:
    total_records_extracted = total_records_extracted + rec_cnt
    jsonfh = open(json_filename, 'w')
    inter = resp.text
    string_e = inter#.decode('utf-8')
    final = string_e.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ')#.replace('\ ',' ')
    encoded_data = final.encode('utf-8')
    cleaned_data = json.loads(encoded_data)
    json.dump(cleaned_data, jsonfh, indent=None)
    jsonfh.close()
except ValueError as e:
    tb = traceback.format_exc()
    print tb
    print "|********************************************************|"
    print  e
    print "|********************************************************|"
    sys.exit(1)

很多开发人员都面临这个问题。许多地方都要求使用.decode('utf-8')或在Python顶部使用# _*_ coding:utf-8 _*_

它仍然没有帮助。

有人可以帮助我解决这个问题吗?

这是痕迹:

Traceback (most recent call last):
File "/Users/SM/PycharmProjects/zendesk/zendesk_tickets_api.py", line 102, in main
cleaned_data = json.loads(encoded_data)
File "/Users/SM/anaconda/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/Users/SM/anaconda/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Users/SM/anaconda/lib/python2.7/json/decoder.py", line 380, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Invalid escape: line 1 column 2826494 (char 2826493)
|********************************************************|
Invalid escape: line 1 column 2826494 (char 2826493)
inter = resp.text
string_e = inter#.decode('utf-8')
encoded_data = final.encode('utf-8')

text属性是一个Unicode字符串,使用编码的任何编码请求模块可以从HTTP标头使用的任何编码的Requests模块。

都可以使用。

您可能不想要那个;JSON对编码应该是什么有自己的想法,因此您应该让JSON解码器从resp.content中获取原始响应字节并将其直接传递到json.loads

更重要的是,请求还有一种快捷方式可以执行相同的操作: resp.json()

final = string_e.replace('\n', ' ').replace('\t', ' ').replace('\r', ' ')#.replace('\ ',' ')

试图在JSON-string-Literal格式输入上执行此操作是一个坏主意:您会错过一些有效的逃生,并且错误地避免了其他人。您的实际错误与Unicode根本无关,这是因为此替换是在缩合输入。例如,考虑输入JSON:

{"message": "Open the file C:\newfolder\text.txt"}

更换后:

{"message": "Open the file C: ewfolder ext.txt"}

显然没有有效的json。

您应该让json解码输入,然后过滤结构化输出中的任何字符串,而不是尝试在JSON编码的字符串上操作。这可能涉及使用递归函数进入每个数据的每个级别,以寻找要过滤的字符串。例如

def clean(data):
    if isinstance(data, basestring):
        return data.replace('n', ' ').replace('t', ' ').replace('r', ' ')
    if isinstance(data, list):
        return [clean(item) for item in data]
    if isinstance(data, dict):
        return {clean(key): clean(value) for (key, value) in data.items()}
    return data
cleaned_data = clean(resp.json())

最新更新