Znak nowego wiersza CSV widoczny w błędzie pola bez cudzysłowu

121

następujący kod działał do dzisiaj, kiedy zaimportowałem z komputera z systemem Windows i otrzymałem ten błąd:

znak nowej linii widoczny w niecytowanym polu - czy musisz otworzyć plik w trybie uniwersalnej nowej linii?

import csv

class CSV:


    def __init__(self, file=None):
        self.file = file

    def read_file(self):
        data = []
        file_read = csv.reader(self.file)
        for row in file_read:
            data.append(row)
        return data

    def get_row_count(self):
        return len(self.read_file())

    def get_column_count(self):
        new_data = self.read_file()
        return len(new_data[0])

    def get_data(self, rows=1):
        data = self.read_file()

        return data[:rows]

Jak mogę rozwiązać ten problem?

def upload_configurator(request, id=None):
    """
    A view that allows the user to configurator the uploaded CSV.
    """
    upload = Upload.objects.get(id=id)
    csvobject = CSV(upload.filepath)

    upload.num_records = csvobject.get_row_count()
    upload.num_columns = csvobject.get_column_count()
    upload.save()

    form = ConfiguratorForm()

    row_count = csvobject.get_row_count()
    colum_count = csvobject.get_column_count()
    first_row = csvobject.get_data(rows=1)
    first_two_rows = csvobject.get_data(rows=5)
GrantU
źródło
Odpowiedź rectummelancolique poniżej rozwiązała mój podobny problem. stackoverflow.com/a/17315726/3131666
kmantel

Odpowiedzi:

181

Dobrze będzie zobaczyć sam plik csv, ale może to zadziałać, spróbuj, zamień:

file_read = csv.reader(self.file)

z:

file_read = csv.reader(self.file, dialect=csv.excel_tab)

Lub otwórz plik za pomocą universal newline modei przekaż go csv.reader, na przykład:

reader = csv.reader(open(self.file, 'rU'), dialect=csv.excel_tab)

Lub użyj w splitlines()ten sposób:

def read_file(self):
    with open(self.file, 'r') as f:
        data = [row for row in csv.reader(f.read().splitlines())]
    return data
alecxe
źródło
To teraz daje ten sam błąd, ale teraz rozpoczyna się upload.num_records = csvobject.get_row_count ()
GrantU
1
a kiedy wypróbowuję wersję podzielonych linii (która jest bardzo fajna dzięki), otrzymuję koercję do Unicode: potrzebuję ciągu lub bufora, znaleziono
S3BotoStorageFile
4
Jaka opcja ostatecznie zadziałała? Btw, czytasz plik dwukrotnie: w get_row_count()i get_column_count()- rozważenie odczytu pliku w __init__i zapamiętać dataw self.data, a następnie używać go w innych metodach.
alecxe
+1 dla splitlines (), co pozwala uniknąć mieszania się z różnymi opcjami formatowania w OSX. Mam nadzieję, że działa również na innych platformach ...
python1981
Świetna odpowiedź. Jednak użycie - "dialect = csv.excel_tab" skręca dane wyjściowe, gdy jest używane z csv.DictReader. Tylko opcje „rU” działają jednak magicznie
Murphy
52

Zdaję sobie sprawę, że to stary post, ale napotkałem ten sam problem i nie widzę poprawnej odpowiedzi, więc spróbuję

Błąd Pythona:

_csv.Error: new-line character seen in unquoted field

Spowodowane próbą odczytania plików CSV dla komputerów Macintosh (sformatowanych przed systemem OS X). Są to pliki tekstowe, które używają CR na końcu wiersza. W przypadku korzystania z MS Office należy wybrać opcję zwykły CSV format lub CSV (MS-DOS) . Nie używaj CSV (Macintosh) jako typu „zapisz jako”.

Moją preferowaną wersją EOL byłaby LF (Unix / Linux / Apple), ale nie sądzę, aby MS Office zapewniał opcję zapisywania w tym formacie.

g.kovatchev
źródło
4
MS DOS Comma Separated nie działa dla mnie (ten sam błąd), ale Windows Comma Separated.
tmthyjames
3
Jeśli korzystasz z komputera Mac, to jest absolutnie poprawna odpowiedź.
HashHazard
Ten sam problem występuje w systemie OS X. Muszę utworzyć nowy plik CSV. Zwykłe zapisanie aktualnego w zwykłym formacie CSV lub CSV (MS-DOS) nie rozwiązuje problemu.
Pyderman
1
W systemie OS X działał plik CSV z separacją przecinkami w systemie Windows, natomiast w systemie MS DOS z separacją przecinkami nie.
user2348114
31

W systemie Mac OS X zapisz plik CSV w formacie „Windows z przecinkami (.csv)”.

BoltzmannBrain
źródło
1
dzięki, to był potrzebny składnik, ponieważ używam Maca w / MS Office.
travellingbones
18

Jeśli tak się stanie na komputerze Mac (tak jak mnie):

  1. Zapisz plik jako CSV (MS-DOS Comma-Separated)
  2. Uruchom następujący skrypt

    with open(csv_filename, 'rU') as csvfile:
        csvreader = csv.reader(csvfile)
        for row in csvreader:
            print ', '.join(row)
Nimo
źródło
2
Właśnie wstrząsnąłeś moim światem.
kta
5

Spróbuj dos2unixnajpierw uruchomić w systemie Windows zaimportowane pliki

rectummelancolique
źródło
naprawdę nie ma opcji, potrzebuję, aby umożliwić użytkownikowi przesyłanie csv z systemu Windows i Mac bez żadnych specjalnych modyfikacji. Import został zapisany z Excela (Windows) jako CSV, więc może jest coś więcej, co trzeba zrobić w Pythonie, aby je przeczytać?
GrantU
@GrantU Masz na myśli system Mac OS X 10.0 lub nowszy, a nie Mac OS 9 lub starszy, prawda? Między 9 a 10 system Mac OS przełączył się z \x0dkońcówek linii (ProDOS) na zakończenia linii \x0a(UNIX).
Damian Yerrick
2

To jest błąd, z którym się spotkałem. Zapisałem plik .csv w MAC OSX.

Podczas zapisywania zapisz go jako „Windows Comma Separated Values ​​(.csv)”, co rozwiązało problem.

Suraj
źródło
1

To działało dla mnie na OSX.

# allow variable to opened as files
from io import StringIO

# library to map other strange (accented) characters back into UTF-8
from unidecode import unidecode

# cleanse input file with Windows formating to plain UTF-8 string
with open(filename, 'rb') as fID:
    uncleansedBytes = fID.read()
    # decode the file using the correct encoding scheme
    # (probably this old windows one) 
    uncleansedText = uncleansedBytes.decode('Windows-1252')

    # replace carriage-returns with new-lines
    cleansedText = uncleansedText.replace('\r', '\n')

    # map any other non UTF-8 characters into UTF-8
    asciiText = unidecode(cleansedText)

# read each line of the csv file and store as an array of dicts, 
# use first line as field names for each dict. 
reader = csv.DictReader(StringIO(cleansedText))
for line_entry in reader:
    # do something with your read data 
Rezonans
źródło
1

Wiem, że odpowiedź trwa od dłuższego czasu, ale nie rozwiązuje mojego problemu. Używam DictReader i StringIO do odczytu csv z powodu innych komplikacji. Udało mi się rozwiązać problem w prostszy sposób, wyraźnie zastępując ograniczniki:

with urllib.request.urlopen(q) as response:
    raw_data = response.read()
    encoding = response.info().get_content_charset('utf8') 
    data = raw_data.decode(encoding)
    if '\r\n' not in data:
        # proably a windows delimited thing...try to update it
        data = data.replace('\r', '\r\n')

Może nie być rozsądne w przypadku ogromnych plików CSV, ale działało dobrze w moim przypadku użycia.

Dougyfresh
źródło
Który rozwiązał mój problem, dzięki Spójrz! Tutaj
AOF
0

Alternatywne i szybkie rozwiązanie: napotkałem ten sam błąd. Ponownie otworzyłem "dziwny" plik csv w GNUMERIC na mojej maszynie lubuntu i wyeksportowałem go jako plik csv. To rozwiązało problem.

p699
źródło