Ошибка при парсинге csv файла
Доброго времени суток.
Вкратце - есть устройство, генерирующее логи в формате CSV. Есть прога, которую я написал для чтения этих логов с FTP и построения графика (еще не готова, но основной функционал работает).
Проблема вот в чем: часть файлов читается, часть - нет. Кодировки проверял, всякие LF+CR тоже, еще что-то проверял, всего уже не помню.
Помогите пожалуйста определить где проблема - у меня в коде (я пока еще новичок), в самих CSV или может в сторонних модулях?
Lazarus 1.8.4, FPC 3.0.4., используются csvdocument и synapse.
uses
Classes, SysUtils, FileUtil, TAGraph, TASeries, TATransformations, TATools,
Forms, Controls, Graphics, Dialogs, StdCtrls, DBGrids, Grids, ComCtrls,
ExtCtrls, FileCtrl, EditBtn, Buttons, Arrow, csvdocument, TAChartAxis,
Ipfilebroker, RTTICtrls, laz_synapse, ftpsend;
type csvLog=class(TCSVDocument)
public
Title,Date,Sample,Data:string;
Combination: boolean;
Units,Combi:array[0..16] of string;
ur:integer;
//загрузка данных и обработка шапки файла
procedure FTPReadInfo(filename:string);
//поиск № строки по тексту в первой колонке
function RowSearch(text:string):Integer;
//поиск № колонки по тексту и номеру строки
function ColSearch(text:string;CRow:Integer):Integer;
end;
var
Form1: TForm1;
csv:csvLog;
test,s0: string;
syn1,syn2,syn9:integer;
autoshift,combination:boolean;
limits:array[1..10,1..2] of real;
axisind:array[1..6] of Integer;
const
COLORS: array [0..15] of Integer =
($000080,$008000,$008080,$800000,$800080,$808000,$808080,$C0C0C0,$0000FF,$00FF00,$00FFFF,$FF0000,$FF00FF,$FFFF00,$000000,$F0CAA6);
implementation
procedure csvLog.FTPReadInfo(filename:string);
var i,dr,cr: integer;
begin
csv.Clear;
//чтение из файла в режиме возможной докачки
if Form1.FTPSend.RetrieveFile(filename,true) then Self.LoadFromStream(Form1.FTPSend.DataStream) else exit;
//заголовок файла
Title:='TITLE: '+Cells[1,RowSearch('TITLE')];
//формирование даты
dr:=RowSearch('TRG_TIME');
Date:='TRG_TIME: '+Cells[3,dr]+'/'+Cells[2,dr]+'/20'+Cells[1,dr]+' '+Cells[4,dr]+':'+Cells[5,dr]+':'+Cells[6,dr];
//интервал замеров
Sample:='TRG_SAMPLE: '+Cells[1,RowSearch('TRG_SAMPLE') ]+' ms';
//массив заголовков данных
ur:=RowSearch('UNIT');
Combination:=false;
Units[0]:='UNIT: ';
for i:=1 to ColCount[ur] do
begin
Units[i]:=Cells[i,ur];
end;
//подсчет кол-ва строк с данными
Data:='DATA: '+IntToStr(RowCount-ur-2)+' lines';
//массив заголовков данных для комбинированного файла
cr:=RowSearch('COMBI');
if Cells[0,cr]='COMBI' then
begin
Combination:=true;
Combi[0]:='COMBI: ';
for i:=1 to ColCount[cr-1] do
begin
Combi[i]:=Cells[i,cr]+',';
end;
end;
end;
function csvLog.RowSearch(text:string):Integer;
var i:integer;
begin
i:=0;
while (Self.Cells[0,i]<>text) and (i
result:=i;
end;
function csvLog.ColSearch(text:string;CRow:Integer):Integer;
var i:integer;
begin
i:=0;
while (Self.Cells[i,CRow]<>text) and (i
result:=i;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
csv.Free;
FTPSend.Logout;
FTPSend.Free;
end;
//обновление списка файлов
procedure TForm1.UpdateFl;
var LI: TlistItem;
I: Integer;
begin
ListView1.Items.BeginUpdate;
try
ListView1.Items.Clear;
//создаем элемент для перехода на один уровень вверх
LI:=ListView1.Items.Add;
LI.Caption:='[. ]';
//заполняем список информацией об объектах в текущей директории
for I := 0 to FTPSend.FtpList.Count-1 do
begin
LI:=ListView1.Items.Add;
LI.Caption:=FTPSend.FtpList[i].FileName;
if FTPSend.FtpList[i].Directory then
Li.SubItems.Add('Папка')
else
Li.SubItems.Add('Файл');
LI.SubItems.Add(IntToStr(FTPSend.FtpList[i].FileSize));
LI.SubItems.Add((DateToStr(FTPSend.FtpList[i].FileTime)));
end;
finally
ListView1.Items.EndUpdate;
end;
end;
//загрузка данных в таблицу
procedure LoadGrid(Grid:TStringGrid);
var col,row:integer;
begin
Grid.BeginUpdate;
Grid.Clear;
Grid.RowCount:=csv.RowCount;
Grid.ColCount:=csv.ColCount[csv.ur+1];
for col:=0 to Grid.ColCount-1 do
// "row+csv.ur" задает сдвиг по строкам для вывода только данных с первой строки таблицы
for row:=0 to Grid.RowCount-1 do Grid.Cells[col,row]:=csv.Cells[col,row+csv.ur];
Grid.EndUpdate;
end;
//замена точки на запятую, вычисление максимумов и точки синхронизации
procedure ReplGrid(Grid: TStringGrid);
var i,y,c,x:integer;
curr: real;
begin
syn1:=0; syn2:=0;
for x:=1 to Grid.ColCount-1 do
for y:=1 to 2 do limits[x,y]:=0.0; //обнуление массива пределов
Grid.BeginUpdate;
for i:=1 to Grid.RowCount-1 do begin
for c:=1 to Grid.ColCount-1 do
begin
if Grid.Cells[c,i]='' then break;
Grid.Cells[c,i]:=StringReplace(Grid.Cells[c,i],'.',',',[rfReplaceAll, rfIgnoreCase]); //замена
curr:=StrToFloat(Grid.Cells[c,i]);
if curr>limits[c,1] then limits[c,1]:=curr; //максимум
if curr if (Grid.Col=8) and (curr<>0) and (syn1<>0) then syn1:=Grid.Row; //точка синхронизации
end;
end;
Form1.Memo1.Lines.Add(FloatToStr(limits[2,1])+'/'+FloatToStr(limits[2,2])+', '+FloatToStr(limits[3,1])+'/'+FloatToStr(limits[3,2]));
Grid.EndUpdate;
end;
//отображение позиции трекбара
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
Label1.Caption:=IntToStr(TrackBar1.Position);
end;
Importing a CSV file can be frustrating. We’ve all struggled with importing and re-importing a file that still contains pesky, difficult-to-identify issues. While CSV import errors can vary widely, we’ve noticed that people are likely to encounter the same handful of CSV parsing errors over and over again. If you learn how to identify and address these errors, importing data can take considerably less time and energy… things we’d all like to have more of.
We’re here to help, both with the five tips below, and with our remote browser for CSV files in the cloud. CSV Studio offers a robust parser and automated error correction for non-conforming and badly formatted CSV files. It enables you to remotely browse files on a data server, automatically identify and correct errors, and export the file to a database free from parsing errors. Watch the demos to learn more.
Even if this is not the most prevalent issue, this is definitely the first issue you can encounter when dealing with CSV. If you use python to process data, this issue will show up very quickly since python I/O will throw an exception at the first sign of trouble. Many parsers cannot display or process a text field with an illegal codepoint and you are forced to immediately find the correct encoding before attempting any further diagnostic.
A utility like the ‘file -e’ command may work if there are enough codepoints to work with. Be aware that even though most of the internet and personal computers take a default UTF-8 encoding for granted, ISO-8859 Latin-1 is as good a bet as any for data originating from a database.
If the column separator appears unescaped in a text field, this will cause the line to have an extra column. Typically the problem will appear when the CSV file is not using double quotes to enclose text and number fields. Names and addresses are often the result of keyboard entry which means that they can contain all kinds of control characters: /, \ , |, ^, left and right arrows, carriage return, linefeeds, etc…
The rational fix is to re-export the file using double-quotes to enclose columns. If this is not possible and it becomes necessary to remove the extra separators, using CSV Studio to escape the extra separators may help you keep your sanity.
Many CSV files take the sensible precaution of enclosing all text inside quoted strings. An unescaped double-quote becomes a potential issue.
All the data is prudently enclosed in double-quotes, but the text already contained random double-quotes.
The accidental use of DJ”S instead of DJ’S creates a single issue in a file with 600,000 lines. This issue is fatal: the rest of the file appears as one single line. The best approach is to re-export the CSV file and escape the double-quotes correctly. If it becomes necessary to do so after the fact, CSV Studio has an algorithm to find the extra double-quotes to be escaped.
Unix-style files often use backslash (\) inside of quoted strings to escape the string delimiter.
> “This string has a \” in it”
However instead of using backslash, RFC-4180 CSV files double up the string delimiter as an escape mechanism.
> “This string has a “” in it”
When encoding CSV files, one of those escape mechanisms should be consistently applied. However we sometimes encounter files that use both escape methods at the same time. This creates ambiguity whenever an escape sequence is encountered (see table).
Line endings are not specifically a CSV issue. Windows and Unix line endings differ, and this will of course affect data files the same as for any other file. The official RFC 4180 line separator for CSV is a CRLF sequence (A carriage return character followed by a new line character). When processing a CSV file with CRLF line endings it is not unusual to find an undesirable ^M (or CR) character at the end of every line. This can even cause issues with some CSV parsers. Processing the file with the dos2unix utility is the standard way of resolving this issue.
Have a really bad CSV file you want to share? Interested in an easy way to display and fix those issues without home-made regex scripting? Read this post, visit the website or email.
Traceback (most recent call last):
File "C:\python\main.py", line 53, in
parser()
File "C:\python\main.py", line 48, in parser
save_doc(cards, CSV)
File "C:\python\main.py", line 33, in save_doc
writer.writerow()
TypeError: writer.writerow() takes exactly one argument (0 given)
Ошибка>
Простой 5 комментариев
Конечно выдает ошибку, у вас отступов нет. И уровень вопроса "средний"- такое себе ставить, для вас то может и средний, но для людей прочитавших хоть одну книжку по Python - думаю что "легкий" (хотя без самой ошибки я думаю даже "сложный" - слишком низкий уровень)
Иван Корякин, сложность и отступы пофиксили, осталось скинуть текст ошибки, и тогда думаю вам помогут.
sswwssww, С отступами всё хорошо, вот ошибка:
Traceback (most recent call last):
File "C:\python\main.py", line 53, in
parser()
File "C:\python\main.py", line 48, in parser
save_doc(cards, CSV)
File "C:\python\main.py", line 31, in save_doc
with open(path, "w", newline='') as file:
PermissionError: [Errno 13] Permission denied: 'cards.csv'
Иван Корякин, на счет отступов это был сарказм, вы сюда код скинули не обернув его в соответствующий тег(модератор уже принял исправления, ничего делать не нужно). Лучше вам добавить текст ошибки к вопросу.
- вот отсюда удалите лишний вызов writer.writerow()
"PermissionError: [Errno 13] Permission denied: 'cards.csv'" - судя по ошибке у вас недостаточно прав на запись. Попробуйте запустить скрипт от имени администратора, либо поменяйте путь куда записываете файл на такой, в котором не нужны особые права.
Есть работающий парсер, который переводит текстовый файл в csv. Исходный текстовый файл имеет вот такой формат:
Этот файл пропускаю через вот такой скрипт парсера:
Получается на выходе вот такой CSV файл:
Всё хорошо. Да, не совсем. У нас всего один Карандаш. А должно быть два! Отсутствует тот, что без child. Но даже если в исходном файле было бы две строки без child, всё равно в csv файл попал бы только один.
Помогите разобраться, почему так происходит.
Удаление конкретной строки из списка строк, при этом не трогать дублирующие строки
Необходимо из списка удалить конкретную строку, при этом не затронуть дублирующие строки. Как.
Bat - файл для чтения только одной строки из файла CSV
Добрый день! Подскажите пожалуйста как сделать батник чтобы он выводил только одну (2, 3, 4. ).
Считать строки из csv файла, все слова заключить в кавычки и разделить запятой. Рез. записать в текстовый файл
Доброго времени суток, столкнулся со следующего рода проблемой, Нужно считать строки из csv файла.
Почему берется исключение при парсинге
Столкнулся с такой проблемой, есть у меня код, в 13 студии он работает нормально, нет никаких.
Очистить строки при парсинге
Добрый день!По окончанию парсинга страниц, получаю таблицу такого формата. RIH8
Ошибка при парсинге xml файла
Добрый день! При парсинге xml файла возникает ошибка, при чем возникает по середине процесса.
Ошибка при парсинге чисел из файла
StreamReader read = new StreamReader($@"D:\Програми\Projects visual studio\Labor4\Mas\.txt");.
Почему обарабывается не весь csv файл?
В итоговый файл сохраняется 226 строк. В то время как всего в исходном там свыше 2000. Куда.
Часто в работе мы сталкиваемся с неприятной особенностью выгрузок CSV через инструмент PL SQL Developer – «сохранение в файл csv результата выполнения запроса».
Для дальнейшего анализа выгруженный файл csv обычно требуется загрузить в pandas.dataframe или в другую СУБД.
При попытке загрузки файла мы сталкиваемся с неприятными ошибками вроде нечитаемых символов, которые pandas не может соотнести с таблицей кодировки: OSError: Initializing from file failed.
Как мы решаем этот вопрос?
Исследуем вопрос, проведем анализ данных csv файла.
Прочитаем несколько срок из файла и выведем результат в консоль:
if __name__ == '__main__': with open(r'C:\Users\user\Desktop\editOBScsv\1.csv', 'r', encoding='utf-8', errors='ignore') as fo: c = 0 for row in fo: print(row) c += 1 if c == 2: break
- в данном случае указываем обязательный атрибут errors='ignore', который помогает игнорировать символы, не совпадающие с таблицей кодировки.
Вывод в консоль в бинарном варианте чтения:
if __name__ == '__main__': with open(r'C:\Users\Desktop\editOBScsv\нулевые графики.csv', 'rb') as fo: c = 0 for row in fo: print(row) c += 1 if c == 1: break
b'i\xbb?"ID \xd0\xba\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb0";"\xd0\xa1\xd1\x83\xd0\xbc\xd0\xbc\xd0\xb0 \xd0\xba\xd1\x80\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb0";"\
Обратите внимание на первые 2 символа '?' (бинарный вариант i\xbb?). Именно они мешают методу pandas.read_csv корректно прочитать файл в DataFrame, а так же препятствуют загрузки файла в СУБД.
Далее рассмотрим три варианта решения.
Если файл размера до 1.2 ГБ – файл открывается стандартным блокнотом.
Решение: Открыть файл – удалить первые два символа – сохранить и использовать в pandas/СУБД.
НО! Файлы более 1.2ГБ, блокнот, Notepad ++ — не откроют.
Установить навороченный текстовый редактор, например – EmEditor работающий с большими текстовыми файлами. Открыть файл – удалить первые два символа – сохранить и использовать в pandas/СУБД.
Csv – это текстовый файл, последовательность символов. Решение, предложенное ниже использует встроенные библиотеки. Оно заключается в построчном чтении строк, при этом первая строка обрезается с левой стороны на 2 символа следующей конструкцией row = row[2:].
На выходе получаем обработанный файл, сохраненный в указанной директории.
pathRead – указываем путь к файлу, содержащему недопустимые символы,
pathWrite – указываем пусть сохранения обработанного файла
import time if __name__ == '__main__': prTimeStart = time.process_time() cf = 0 pathRead = r'C:\Users\Desktop\editOBScsv\нулевые графики.csv' pathWrite = r'C:\Users\Desktop\editOBScsv\out.csv' with open(pathRead, 'r', encoding='utf-8', errors='ignore') as fo: with open(pathWrite, 'w', encoding='utf-8') as fw: for row in fo: cf += 1 print('Row counts = %d' % cf) fo.seek(0) print(f'Starting to copy and past rows in the new file..') cf = 0 for row in fo: if cf == 0: print('First row before changing:\n%s' % row) row = row[2:] print('First row after changing:\n%s' % row) cf += 1 fw.writelines(row) print('End copy row in new file.') print('Time executed copy/past = %f' % (time.process_time() - prTimeStart))
C:\Anaconda3\python.exe C:/Users/PycharmProjects/editODScsv.py Row counts = 3696862 Starting to copy and past rows in the new file.. First row before changing: i?"ID кредита";"Сумма кредита…. First row after changing: "ID кредита";"Сумма кредита….. End copy row in new file. Time executed copy/past = 275.781250 Process finished with exit code 0
Читайте также: