Найти - Пользователи
Полная версия: Парсер файла csv на python3
Начало » Python для новичков » Парсер файла csv на python3
1 2
whoami217
Добрый день. Есть небольшой файл/пример csv/excel, который нужно пропарсить особым образом. В самом файле содержится 3 колонки. На первой строчке находятся названия параметров. Каждый параметр принадлежит к одной колонке под ним. Необходимо, чтобы при запуске кода:
1. спрашивали название файла, который нужно пропарсить,
2. добавляли новый файл csv, куда необходимые нам колонки вставлялись в файл,
3. спрашивали, какие параметры мы хотим получить в новом файле txt,
4. вводили параметры,
5. и записывали эти колонки с параметрами и их значениями в новый файл.

Проблема в том, что не происходит запись в новый файл. То есть открываю файл, а там пусто.

Приложен файл и мой код. Можете ознакомиться.
Также можете предложить свой альтернативный код.

 import csv
import string
 
fname = input("Enter a file name: ")
outputfile = "out.csv"
 
try:
    fhand = open(fname, mode='r')
    fcopy = open(outputfile, mode='w')
    #fcopy2 = open(outputfile, mode='r')
except:
    print ("File don’t exist: ", fname)
    exit()
rdn = csv.reader(fhand, delimiter=';')
wrtr = csv.writer(fcopy, delimiter=';')
for title in list(rdn)[:1]:
    print("This file has parameters: ")
    print(title)
    
'''
rdn = csv.reader(fhand, delimiter=';')
i = ' '.join(list(rdn)[0])
print(i)
'''
while True:
    print("---------------------------------------------------------")
    print("If you want to EXIT this program then type - done")
    param = input("Enter the required parameter: ") 
    
    if param == "done":
        break
    
    if not (param in title):
        print("This parameter doesn't exist. Please try again")
        exit()
    rdn = csv.reader(fhand, delimiter=';')
    print("This file has parameters: ")
    print(title)
    titleIndex = title.index(param)
    print(titleIndex)
    wrtr = csv.writer(fcopy, dialect='excel')
    for row in rdn:
        wrtr.writerow(row)
    print("---------------------------------------------------------")
'''    
rdn = csv.reader(fhand, delimiter=';')
for c in list(rdn)[:1]:
    print(c)
wrtr2 = csv.reader(fcopy2, delimiter=';')
for b in wrtr2:
    print(b)
'''
fhand.close()
fcopy.close()
py.user.next
whoami217
Проблема в том, что не происходит запись в новый файл. То есть открываю файл, а там пусто.
Нужно файл перематывать через fhand.seek(0) или закрывать и открывать заново.
whoami217
py.user.next
Нужно файл перематывать через rdn.seek(0) или закрывать и открывать заново.
Закрывать и открывать файл заново не получается, так как все попытки использовать объект файла после вызова fhand.close() будут завершены неудачей:
ValueError: I/O operation on closed file.

И используя rdn.seek(0) выдаёт ошибку:
AttributeError: ‘_csv.reader’ object has no attribute ‘seek’

Пробовала сделать так перед while:
fhand.close()
fhand = open(fname, mode='r', encoding='utf-8')
rdn = csv.reader(fhand, delimiter=';')
Ввела только один параметр и в out.csv записалось всё, что было в исходном файле. При чём как-то скомкано. Файл out.csv прикреплен к этому сообщению.
Также в самом цикле while перед wrtr = csv.writer(fcopy, dialect='excel') записала эти три строчки, но в out.csv записалось тоже самое.
py.user.next
Я поправил там выше rdn на fhand.
whoami217
py.user.next, спасибо. Кое-что получилось. Изменила rdn на fhand: fhand.seek(0). Программа всё хорошо восприняла (без ошибок). Записалось в файл не скомкано (в отдельной ячейке), но проблема теперь в том, что записывает всё, что было в исходном файле. И пропускает каждую чётную строку.
Файл out.csv прикреплен к этому сообщению.
 import csv
import string
 
fname = input("Enter a file name: ")
outputfile = "out.csv"
 
try:
    fhand = open(fname, mode='r', encoding='utf-8')
    fcopy = open(outputfile, mode='w')
    #fcopy2 = open(outputfile, mode='r')
except:
    print ("File don’t exist: ", fname)
    exit()
rdn = csv.reader(fhand, delimiter=';')
#wrtr = csv.writer(fcopy, delimiter=';')
for title in list(rdn)[:1]:
    print("This file has parameters: ")
    print(title)
    
'''
rdn = csv.reader(fhand, delimiter=';')
i = ' '.join(list(rdn)[0])
print(i)
'''
while True:
    print("---------------------------------------------------------")
    print("If you want to EXIT this program then type - done")
    param = input("Enter the required parameter: ") 
    
    if param == "done":
        break
    
    if not (param in title):
        print("This parameter doesn't exist. Please try again")
        exit()
    rdn = csv.reader(fhand, delimiter=',')
    print("This file has parameters: ")
    print(title)
    titleIndex = title.index(param)
    print(titleIndex)
    fhand.seek(0)
    wrtr = csv.writer(fcopy, dialect='excel')
    for row in rdn:
        wrtr.writerow(row)
    print("---------------------------------------------------------")
fhand.close()
fcopy.close()
py.user.next
whoami217
И пропускает каждую чётную строку.
Открывать файлы нужно в бинарном режиме (rb и wb), так как текстовый режим влияет на концы строк, которые в csv строго определены как \r\n.
whoami217
py.user.next, изменила строки:
fhand = open(fname, mode='rb')
fcopy = open(outputfile, mode='wb')
Исключила try и except, так как при вводе названия исходного файла убивало весь процесс выполнения файла. И получила следующую ошибку:
Enter a file name: text.csv
Traceback (most recent call last):
for title in list(rdn):
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
Присвоила к строке fhand = open(fname, mode='rb') encoding='utf-8' => fhand = open(fname, mode='rb', encoding='utf-8'), и снова получила ошибку:
Enter a file name: text.csv
Traceback (most recent call last):
File “C:\Users\Гранит-Электрон\Desktop\Work\Алёна\Other\for work python\csv_fileColom.py”, line 8, in <module>
fhand = open(fname, mode='rb', encoding='utf-8')
ValueError: binary mode doesn't take an encoding argument
py.user.next
Значит, я неправильно написал про режимы. Во втором питоне так делали.
Пример из документации для третьего питона.
  
import csv
with open('eggs.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        print(', '.join(row))
Текстовый режим с отменой преобразования концов строк.
whoami217
py.user.next, если записывать как вы предлагаете (если я Вас правильно поняла)
 import csv
import string
 
fname = input("Enter a file name: ")
outputfile = "out.csv"
try:
    fhand = open(fname, mode='r', newline='')
    fcopy = open(outputfile, mode='w')
except:
    print ("File don’t exist: ", fname)
    exit()
rdn = csv.reader(fhand, delimiter=' ')
for i in rdn:
    print(', '.join(i))
    
#rdn = csv.reader(fhand, delimiter=';')
for title in list(rdn)[:1]:
    print("This file has parameters: ")
    print(title)
    
'''
rdn = csv.reader(fhand, delimiter=';')
i = ' '.join(list(rdn)[0])
print(i)
'''
while True:
    print("---------------------------------------------------------")
    print("If you want to EXIT this program then type - done")
    param = input("Enter the required parameter: ") 
    
    if param == "done":
        break
    
    if not (param in title):
        print("This parameter doesn't exist. Please try again")
        exit()
    rdn = csv.reader(fhand, delimiter=',')
    print("This file has parameters: ")
    print(title)
    titleIndex = title.index(param)
    print(titleIndex)
    fhand.seek(0)
    wrtr = csv.writer(fcopy, dialect='excel')
    for row in rdn:
        wrtr.writerow(row)
    print("---------------------------------------------------------")
fhand.close()
fcopy.close()

то выдаётся ошибка и зачем-то print весь содержащийся исходный файл:

Enter a file name: text.csv
avr;atv;bmv
6246.09375;55856.25;38.625
6230.859375;55856.25;38.625
6230.859375;55856.25;38.625
6213.28125;55856.25;38.625
6213.28125;55856.25;38.625
6195.703125;55856.25;38.625
6195.703125;55856.25;38.625
6179.296875;55912.5;42
6179.296875;55912.5;42
6162.890625;55912.5;42
6162.890625;55912.5;42
6146.484375;55912.5;42
6146.484375;55912.5;42
6128.90625;55912.5;42
6128.90625;55912.5;42
6111.328125;55987.5;45.625
6111.328125;55987.5;45.625
6094.921875;55987.5;45.625
6094.921875;55987.5;45.625
6077.34375;55987.5;45.625
6077.34375;55987.5;45.625
6060.9375;55987.5;45.625
6060.9375;55987.5;45.625
6043.359375;56062.5;49.25
6043.359375;56062.5;49.25
6026.953125;56062.5;49.25
6026.953125;56062.5;49.25
6010.546875;56062.5;49.25
6010.546875;56062.5;49.25
———————————————————
If you want to EXIT this program then type - done
Enter the required parameter: bmv
Traceback (most recent call last):
if not (param in title):
NameError: name ‘title’ is not defined
py.user.next
Не надо менять delimiter на пробел. Надо поставить точку с запятой, потому что по умолчанию разделитель - запятая (csv - comma separated values).
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB