Pracuję z kilkoma plikami CSV z następującym kodem:
reader = csv.reader(open(filepath, "rU"))
try:
for row in reader:
print 'Row read successfully!', row
except csv.Error, e:
sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))
Jeden plik zgłasza ten błąd:
file my.csv, line 1: line contains NULL byte
Co mogę zrobić? Wydaje się, że Google sugeruje, że może to być plik Excela, który został nieprawidłowo zapisany jako .csv. Czy jest jakiś sposób na obejście tego problemu w Pythonie?
== AKTUALIZACJA ==
Po komentarzu @ JohnMachin poniżej, próbowałem dodać te wiersze do mojego skryptu:
print repr(open(filepath, 'rb').read(200)) # dump 1st 200 bytes of file
data = open(filepath, 'rb').read()
print data.find('\x00')
print data.count('\x00')
A oto wynik, który otrzymałem:
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1\x00\x00\x00\x00\x00\x00\x00\x00\ .... <snip>
8
13834
Więc plik rzeczywiście zawiera bajty NUL.
od -c
pierwsza linijka?Odpowiedzi:
Jak mówi @ S.Lott, powinieneś otwierać swoje pliki w trybie 'rb', a nie 'rU'. Jednak może to NIE być przyczyną obecnego problemu. O ile wiem, użycie trybu „rU” mogłoby zepsuć cię, jeśli są osadzone
\r
, ale nie spowodowałoby żadnych innych dramatów. Zauważyłem również, że masz kilka plików (wszystkie otwarte za pomocą 'rU' ??), ale tylko jeden powoduje problem.Jeśli moduł csv mówi, że masz w pliku bajt „NULL” (głupia wiadomość, powinna mieć wartość „NUL”), musisz sprawdzić, co jest w pliku. Sugerowałbym, abyś to zrobił, nawet jeśli użycie „rb” spowoduje, że problem zniknie.
repr()
jest (lub chce być) twoim przyjacielem od debugowania. Pokaże jednoznacznie, co masz, w sposób niezależny od platformy (co jest pomocne dla pomocników, którzy nie wiedzą, cood
jest lub co robi). Zrób to:i ostrożnie skopiuj / wklej (nie wpisuj ponownie) wynik do edycji twojego pytania (nie do komentarza).
Zauważ również, że jeśli plik jest naprawdę podejrzany, np. Nie ma \ r lub \ n w rozsądnej odległości od początku pliku, numer linii zgłaszany przez
reader.line_num
będzie (nieprzydatny) 1. Znajdź, gdzie\x00
jest pierwsza (jeśli istnieje), wykonująci upewnij się, że co najmniej tyle bajtów zrzuciłeś za pomocą polecenia repr lub od.
Co
data.count('\x00')
ci powie? Jeśli jest ich wiele, możesz chcieć zrobić coś takiegoabyś mógł zobaczyć bajty NUL w kontekście.
Jeśli widzisz
\x00
na wyjściu (lub\0
w swoimod -c
wyniku), to na pewno masz bajt (y) NUL w pliku i będziesz musiał zrobić coś takiego:Przy okazji, czy obejrzałeś plik (w tym kilka ostatnich wierszy) za pomocą edytora tekstu? Czy faktycznie wygląda jak rozsądny plik CSV, podobnie jak inne pliki (bez wyjątku „bajtu zerowego”)?
źródło
'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1
to "podpis" oznaczający plik dokumentu złożonego OLE2 - np . Plik Excel 97-2003 .XLS . Uważam, że „w edytorze tekstu wygląda to jak całkiem rozsądny plik CSV” za całkowicie niewiarygodne . Musiałeś patrzeć na inny plik, prawidłowy plik CSV, w innym folderze, na innym komputerze lub w innym czasie. Zauważ, żeod
dane wyjściowe nie pochodzą z pliku XLS.csv.reader
bezpośrednio.fo.write(data.replace('\x00', ''))
byćfo.write(data.replace(b'\x00', b''))
? Python 3.6 tutaj ...To działa dla mnie.
źródło
Odczytanie go jako UTF-16 też było moim problemem.
Oto mój kod, który zakończył się działaniem:
Gdzie lokalizacja to katalog twojego pliku csv.
źródło
Ja też wpadłem na ten problem. Korzystając z
csv
modułu Python , próbowałem odczytać plik XLS utworzony w MS Excel i napotkałem wyświetlanyNULL byte
błąd. Rozejrzałem się i znalazłem moduł xlrd Python do odczytu i formatowania danych z plików arkusza kalkulacyjnego MS Excel. Dzięki temuxlrd
modułowi mogę nie tylko poprawnie odczytać plik, ale mogę również uzyskać dostęp do wielu różnych części pliku w sposób, w jaki wcześniej nie mogłem.Pomyślałem, że to może ci pomóc.
źródło
Konwersja kodowania pliku źródłowego z UTF-16 na UTF-8 rozwiązuje mój problem.
Jak przekonwertować plik do utf-8 w Pythonie?
źródło
Możesz po prostu wbudować generator, aby odfiltrować wartości null, jeśli chcesz udawać, że nie istnieją. Oczywiście zakłada się, że bajty zerowe nie są tak naprawdę częścią kodowania i naprawdę są jakimś błędnym artefaktem lub błędem.
źródło
Dlaczego to robisz?
Dokumenty są dość jasne, że musisz to zrobić:
Tryb odczytu musi mieć wartość „rb”.
http://docs.python.org/library/csv.html#csv.reader
źródło
od
lub patrzy na niego w edytorze tekstu, wygląda jak idealnie normalny plik CSV. Jednak kiedy zrzuca pierwsze kilka bajtów za pomocą Pythona repr (), tworzy jak plik Excel .XLS (jego nazwa została zmieniona, aby mieć rozszerzenie CSV).najwyraźniej jest to plik XLS, a nie plik CSV, jak http://www.garykessler.net/library/file_sigs.html potwierdź
źródło
Zamiast czytnika csv używam funkcji read file i split dla stringów:
źródło
Mam ten sam błąd. Zapisałem plik w UTF-8 i zadziałało.
źródło
Zdarzyło mi się to, gdy utworzyłem plik CSV za pomocą OpenOffice Calc. Tak się nie stało, gdy utworzyłem plik CSV w moim edytorze tekstu, nawet jeśli później edytowałem go w programie Calc.
Rozwiązałem problem, kopiując i wklejając w edytorze tekstu dane z mojego pliku utworzonego w programie Calc do nowego pliku utworzonego przez edytor.
źródło
Miałem ten sam problem podczas otwierania pliku CSV utworzonego z usługi sieciowej, która wstawiała bajty NULL do pustych nagłówków. Wykonałem następujące czynności, aby wyczyścić plik:
Zastrzeżenie: pamiętaj, że spowoduje to nadpisanie oryginalnych danych. Upewnij się, że masz jego kopię zapasową. Zostałeś ostrzeżony!
źródło
Dla wszystkich tych, którzy nie znoszą trybu plików `` rU '': właśnie próbowałem otworzyć plik CSV z komputera z systemem Windows na komputerze Mac z trybem pliku `` rb '' i otrzymałem ten błąd z modułu csv:
Otwarcie pliku w trybie „rU” działa poprawnie. Uwielbiam tryb Universal-Newline - oszczędza mi to wiele kłopotów.
źródło
Napotkałem to podczas używania scrapy i pobierania skompresowanego pliku csv bez odpowiedniego oprogramowania pośredniczącego do rozpakowania treści odpowiedzi przed przekazaniem jej do csvreadera. W związku z tym plik nie był w rzeczywistości plikiem csv i odpowiednio wyrzucił
line contains NULL byte
błąd.źródło
Czy próbowałeś użyć gzip.open?
Próbowałem otworzyć plik, który został skompresowany, ale miał rozszerzenie „.csv” zamiast „csv.gz”. Ten błąd pojawiał się, dopóki nie użyłem gzip.open
źródło
Jeden przypadek jest taki - jeśli plik CSV zawiera puste wiersze, ten błąd może się pojawić. Przed przystąpieniem do pisania lub czytania należy sprawdzić wiersz.
Rozwiązałem problem, dodając to sprawdzenie w kodzie.
źródło