2016-06-15 10 views
1

Ich mache einen API-Aufruf und die Antwort hat Unicode-Zeichen. führt die folgenden Fehler diese Antwort in eine Datei zu laden:Unicode-API-Antwort wirft Fehler "Ascii" Codec kann nicht Zeichen u 'u2019' in Position 22462 codieren '

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

alle Kombinationen von Decodierung und -Codierung Versucht (‚UTF-8‘). Hier

ist der Code:

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) 

viele Entwickler dieses Problem konfrontiert. viele Orte haben gebeten, .decode('utf-8') oder mit # _*_ coding:utf-8 _*_ an der Spitze von Python zu verwenden.

Es hilft immer noch nicht.

Kann mir jemand mit diesem Problem helfen.

Hier ist die Spur:

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) 
+0

Nur um sicher zu sein, in welcher Zeile der Interpreter stoppt? – fedterzi

+1

Bitte geben Sie den vollständigen Stack-Trace an. – univerio

+0

Verwenden Sie Anfragen? Wenn ja, benutze 'resp.json()', wenn du willst json –

Antwort

0
inter = resp.text 
string_e = inter#.decode('utf-8') 
encoded_data = final.encode('utf-8') 

Die text Eigenschaft ist eine Unicode-Zeichenfolge, von den ursprünglichen Bytes decodiert unter Verwendung von was auch immer Codierung des Requests Modul im Einsatz von den HTTP-Header erraten sein könnte.

Wahrscheinlich wollen Sie das nicht; JSON hat seine eigenen Vorstellungen darüber, was die Kodierung sein sollte, also sollten Sie den JSON-Dekodierer das tun lassen, indem Sie die rohen Antwortbytes von resp.content nehmen und sie direkt an json.loads übergeben.

Was mehr ist, Requests hat eine Shortcut-Methode, um das gleiche zu tun: resp.json().

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

Der Versuch, dies auf der JSON-String-Literal formatiert Eingang zu tun, ist eine schlechte Idee: Sie einige gültige Fluchten verpassen, und falsch unescape andere. Ihr tatsächlicher Fehler hat überhaupt nichts mit Unicode zu tun, nur dass diese Ersetzung die Eingabe verfälscht. Zum Beispiel sollten Sie die Eingabe JSON:

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

nach dem Austausch:

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

, die eindeutig nicht gültig JSON ist.

Anstatt zu versuchen, mit der JSON-codierten Zeichenfolge zu arbeiten, sollten Sie json die Eingabe dekodieren und dann alle Zeichenfolgen filtern, die Sie in der strukturierten Ausgabe haben. Dies kann beinhalten, eine rekursive Funktion zu verwenden, um in jede Ebene der Daten zu gehen, um nach zu filternden Zeichenfolgen zu suchen. zB

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()) 
+0

das hilft mir bei der Reinigung der Escape-Zeichen. Ich möchte aber auch die Unicode-Daten in die Downstream-Datenbanken schreiben. Wenn ich versuche, die von diesem Code geschriebenen Dateien zu lesen, stößt es auf Unicode-Zeichen wie 'XTREME am 23. Juni \ 020325' – user6471969

+0

' json.loads' konvertiert die Eingabe '\ u2013' in das Zeichen U + 2013 En Dash '-' in Ordnung . – bobince