2013-03-14 7 views
6

Also ich versuche, JSON-Dateien in eine Tab-getrennte Datei zu analysieren. Das Parsen scheint gut zu funktionieren und alle Daten kommen durch. Obwohl das Seltsamste in der Ausgabedatei passiert. Ich habe ihm gesagt, dass er ein Tabulator-Trennzeichen verwenden soll und bei der Ausgabe werden Tabs verwendet, aber es scheint immer noch die einfachen Anführungszeichen zu enthalten. Und aus irgendeinem Grund scheint es auch, den Buchstaben B an den Anfang zu setzen. Ich habe den Header manuell eingegeben, und das funktioniert gut, aber die Daten selbst verhalten sich seltsam. Hier ist ein Beispiel für die Ausgabe, die ich bekomme.Der Python-CSV-Writer fügt Buchstaben an den Anfang jedes Elements und Probleme mit codieren

id created text screen name name latitude longitude place name place type 
b'1234567890' b'Thu Mar 14 19:39:07 +0000 2013' "b""I'm at Bank Of America (Wayne, MI) http://t.co/asdf""" b'userid' b'username' 42.28286837 -83.38487864 b'Bank Of America, Wayne' b'poi' 
b'1234567891' b'Thu Mar 14 19:39:16 +0000 2013' b'here is a sample tweet \xf0\x9f\x8f\x80 #notingoodhands' b'userid2' b'username2' 

Hier ist der Code, den ich verwende, um die Daten zu schreiben.

out = open(filename, 'w') 
    out.write('id\tcreated\ttext\tscreen name\tname\tlatitude\tlongitude\tplace name\tplace type') 
    out.write('\n') 
    rows = zip(ids, times, texts, screen_names, names, lats, lons, place_names, place_types) 
    from csv import writer 
    csv = writer(out, dialect='excel', delimiter = '\t') 
    for row in rows: 
     values = [(value.encode('utf-8') if hasattr(value, 'encode') else value) for value in row] 
     csv.writerow(values) 
    out.close() 

Also hier ist die Sache. Wenn ich dies ohne das utf-8-Bit mache und es einfach gerade ausgäbe, wäre die Formatierung perfekt, wie ich es möchte. Aber wenn Leute Sonderzeichen eingeben, stürzt das Programm ab und kann es nicht verarbeiten.

Traceback (most recent call last): 
    File "tweets.py", line 34, in <module> 
    csv.writerow(values) 
    File "C:\Python33\lib\encodings\cp1252.py", line 19, in encode 
    return codecs.charmap_encode(input,self.errors,encoding_table)[0] 
UnicodeEncodeError: 'charmap' codec can't encode character '\U0001f3c0' in position 153: character maps to <undefined> 

Hinzufügen der utf-8-Bit-es auf die Art der Ausgabe wandelt die Sie hier sehen, aber dann fügt sie alle diese Zeichen auf den Ausgang. Hat jemand darüber irgendwelche Gedanken?

Antwort

6

Sie schreiben Byte-Daten anstelle von Unicode in Ihre Dateien, weil Sie die Daten selbst codieren.

Entfernen Sie die encode Aufrufe zusammen und lassen Python dies für Sie behandeln; Öffnen Sie die Datei mit der UTF8-Codierung und der Rest kümmert sich um sich selbst:

out = open(filename, 'w', encoding='utf8') 

Diese im csv module documentation dokumentiert ist:

Da open() verwendet, um eine CSV-Datei zum Lesen zu öffnen, wird die Datei Standardmäßig werden sie mit der Standardkodierung des Systems in Unicode dekodiert (siehe locale.getpreferredencoding()). Um eine Datei zu entschlüsseln mit einem anderen Codiersystem, verwenden Sie die Codierung Argument offen:

import csv 
with open('some.csv', newline='', encoding='utf-8') as f: 
    reader = csv.reader(f) 
    for row in reader: 
     print(row) 

Das gleiche gilt für das Schreiben in etwas anderes als die System Standard-Kodierung: Geben Sie die Codierung Argument, wenn die Ausgabedatei zu öffnen.

+0

Das hat den Trick gemacht. Vielen Dank! – brian

0

Sie haben mehrere Dinge hier vor, aber zuerst, lassen Sie uns ein wenig Verwirrung aufräumen.

Die Codierung von Nicht-ASCII-Zeichen in UTF-8 bedeutet, dass Sie mehrere Bytes erhalten. Zum Beispiel ist das Zeichen \xf0\x9f\x8f\x80 in UTF-8. Aber das ist immer noch nur ein Zeichen, es ist nur ein Zeichen, das vier Bytes braucht. Wenn Sie die Zeichenfolge in eine Binärdatei schreiben, dann sehen Sie sich diese Datei in einem UTF-8-kompatiblen Werkzeug an (Notepad oder TextEdit oder nur cat auf einem UTF-8-freundlichen Terminal/Shell), Sie werden eine sehen, nicht vier Müllzeichen.

Zweitens b'abc' ist kein String mit b am Anfang hinzugefügt, es ist die repr Darstellung des Byte-String abc. Die b ist nicht mehr ein Teil der Zeichenfolge als die Zitate sind.

Schließlich können Sie in Python 3 eine Datei im Textmodus nicht öffnen und dann Byte-Strings darauf schreiben.Öffnen Sie es entweder im Textmodus mit einer Codierung und schreiben Sie normale Unicode-Zeichenfolgen oder öffnen Sie es im Binärmodus, und schreiben Sie codierte Byte-Zeichenfolgen.

Verwandte Themen