2013-03-14 8 views
6

Próbuję przetworzyć pliki JSON w plik rozdzielany tabulatorami. Parsowanie wydaje się działać dobrze i wszystkie dane są przychodzące. Chociaż najdziwniejsza rzecz dzieje się na pliku wyjściowym. Powiedziałem mu, aby używał ogranicznika tabulacji, a na wyjściu używa kart, ale nadal wydaje się trzymać pojedyncze cytaty. Z jakiegoś powodu wydaje się również, że do początku dodaje się literę B. Ręcznie wpisałem nagłówek i działa to dobrze, ale same dane działają dziwnie. Oto przykład wyjścia, które otrzymuję.Pisarz CSV Pythona dodaje litery na początku każdego elementu i wydaje kodowanie

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' 

Oto kod, którego używam do zapisywania danych.

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

Więc o to chodzi. Jeśli zrobiłbym to bez utf-8 bit i po prostu wyprowadziłem to prosto, formatowanie byłoby idealnie, jak tego chcę. Ale kiedy ludzie piszą znaki specjalne, program się zawiesza i nie jest w stanie go obsłużyć.

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> 

Dodawanie UTF-8 bit konwertuje go do rodzaju produkcji można zobaczyć tutaj, ale potem dodaje wszystkie te znaki do wyjścia. Czy ktoś ma jakieś przemyślenia na ten temat?

Odpowiedz

6

Piszą Państwo dane bajtowe zamiast Unicode do swoich plików, ponieważ sami je kodujecie.

Całkowicie usuń połączenia encode i pozwól, aby Python sobie z tym poradził; otworzyć plik z kodowaniem UTF-8, a reszta dba o siebie:

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

Jest to udokumentowane w csv module documentation:

Od open() służy do otwierania pliku CSV do czytania, plik zostanie domyślnie jest dekodowany na kod Unicode przy użyciu domyślnego kodowania systemu (patrz locale.getpreferredencoding()). Zdekodować plik przy użyciu innego kodowania, należy użyć argumentu kodowania otwarty:

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

To samo stosuje się do pisania w coś innego niż domyślne kodowanie systemu: podać argument kodowania podczas otwierania pliku wyjściowego.

+0

To załatwiło sprawę. Dzięki! – brian

0

Masz tu wiele rzeczy, ale najpierw wyjaśnijmy trochę zamieszania.

Kodowanie znaków nie-ASCII do UTF-8 oznacza, że ​​otrzymujesz wiele bajtów. Na przykład znak jest \xf0\x9f\x8f\x80 w UTF-8. Ale to wciąż tylko jedna postać, to tylko postać, która zajmuje cztery bajty. Jeśli napisasz ciąg do pliku binarnego, spójrz na ten plik w narzędziu kompatybilnym z UTF-8 (Notatnik lub TextEdit, lub po prostu cat na przyjaznym dla UTF-8 terminalu/powłoce), zobaczysz jeden , nie cztery znaki śmieci.

Po drugie, b'abc' nie jest ciągiem znaków z b dodanym na początku, jest to repr reprezentacja ciągu bajtowego . b nie jest już częścią ciągu, niż cytaty.

Wreszcie, w Pythonie 3, nie można otworzyć pliku w trybie tekstowym, a następnie napisać do niego ciągi bajtów.Otwórz go w trybie tekstowym, za pomocą kodowania i napisz zwykłe ciągi znaków unicode lub otwórz je w trybie binarnym i zapisz kodowane ciągi bajtów.

Powiązane problemy