• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Статья Работа с форматом CSV с помощью Python

О формате CSV, а также о том, как работать с ним с помощью Python существует большое множество статей. И, казалось бы, что такого сложного в том, чтобы прочитать или записать данный формат. Однако, вспоминая себя и то время, когда я только начал изучать Python я хорошо помню некоторое недопонимание этого вопроса. Может быть, поэтому я решил написать эту небольшую статью. Конечно же, рассмотреть все тонкости и нюансы думаю, что не получиться, но вот базовые операции с данным типом файлов я постараюсь описать.

000.jpg

Давайте начнем с определения формата. Что же такое CSV-файл? CSV – это аббревиатура. В более развернутом варианте звучит это так - Comma-Separated Values, то есть, значения, разделенные запятыми. Данный формат был разработан для представления табличных данных. Таким образом, каждая строка таблицы соответствует строке текста. В такой строке содержится одно или несколько полей, которые разделены запятыми.

Данный формат достаточно удобен, но, по крайней мере, пока, стандартизирован не полностью. С одной стороны, разделение полей таблицы запятыми достаточно логично. Но, в этом случае возникнет небольшая проблема, суть которой в том, что табличные данные также могут содержать запятые. Частичным решение данной проблемы является использование кавычек, в которые заключается текст, содержащий такие данные.

Со временем появились файлы, которые также попадают под определение CSV, но вот только разделителем в них служит не запятая, а точка с запятой. Или еще один формат, где разделитель – это символ табуляции TSV. Именно поэтому, большинство приложений, которые работают с форматом CSV, позволяют выбирать, что использовать в качестве разделителя или символа кавычек. Для примера, вот скриншот из LibreOffice, где уже при открытии файла можно указать нужные параметры.

01.png

Что же, думаю, что теории, в данном случае достаточно. Давайте приступать к практике. И начнем мы с самого простого. С чтения файлов данного формата с помощью Python.


Чтение файлов CSV

Для выполнения данной операции устанавливать сторонние модули не нужно. Все, что требуется для работы с CSV файлами, есть в Python «из-коробки». Для использования в нашем примере возьмем файл следующего содержания:

02.png


Так выглядит данный файл, если его отрыть в блокноте. Здесь представлены «виртуальные» данные, которые образуют небольшую таблицу, в которой содержаться: Отображаемое имя, Имя, Отчество, Фамилия, Примечание, Номер телефона, Место работы, Должность.

Создадим небольшой код, который выведет данные из таблицы построчно.

Python:
import csv

with open('contacts.csv', 'r', encoding='utf-8') as csv_file:
    caption = ""
    for num, row in enumerate(csv.reader(csv_file, delimiter=',')):
        if num == 0:
            caption = row
            continue
        else:
            for nm, data in enumerate(row):
                print(f'{caption[nm]}: {data}')
            print("\n")

Для начала импортируем модуль csv. Откроем файл с данными на чтение, создадим переменную, в которой будем хранить список с заголовками таблицы. Каждая прочитанная строка здесь будет представлена в виде списка. Затем организуем цикл, в котором итерируемся по строкам из открытого файла. Так как первая строка содержит заголовки, присваиваем ее значение переменной caption и переходим к следующей итерации. Затем, создадим еще один цикл, в котором уже будем итерироваться по списку с данными. Так как у нас есть заголовки, выводим в терминал значение заголовка и содержимое строки. Вот, что в итоге у нас должно получиться:

03.png



Чтение файлов CSV с помощью DictReader

Теперь давайте прочитаем наш файл с контактами несколько иначе. Если в предыдущем примере данные считывались построчно и были представлены в виде списка, то прочитав файл с помощью DictReader, мы получим словарь из каждой строки таблицы, в качестве ключей, в котором, будут заголовки. В нашем примере это выглядит так:

04.png


Таким образом, мы можем модифицировать предыдущий код с учетом использования DictReader.

Python:
import csv

with open('contacts.csv', 'r', encoding='utf-8') as csv_file:
    for row in csv.DictReader(csv_file):
        for data in row:
            print(f'{data}: {row[data]}')
        print("\n")

Здесь все происходит точно также как и в предыдущем примере, за исключением того, что мы уже не забираем значение из первой строки заголовков. Все данные формируются автоматически. Таким образом, для того, чтобы вывести данные, нам нужно проитерироваться по каждому созданному словарю и забрать из него данные, то есть ключ и его значение. Вот результат выполнения данного кода:

05.png


Как мы видим, кода стало несколько меньше, а результат мы получили тот же самый.
Однако следует понимать, что не каждый файл csv содержит заголовки. Потому, нужно учитывать это в своем коде. И использовать нужный способ чтения файла в каждом конкретном случае.


Читаем файл CSV с помощью Pandas

Думаю, как вы уже поняли из заголовка, в данном примере, для чтения файла CSV мы будем использовать стороннюю библиотеку Pandas. Поэтому, для начала ее нужно установить с помощью pip. Для этого пишем в терминале:

pip install pandas

Конечно же, чтение файлов данного формата – это только один из множества методов работы с данными, которые предоставляет данная библиотека. Но, в данном случае, мы будем рассматривать именно его. И здесь будет представлено еще меньше кода, так как с помощью pandas можно уложиться буквально в три строки. И данные, которые будут прочитаны из файла, выведутся в терминал уже в табличном виде. Перейдем к коду.

Python:
import pandas

df = pandas.read_csv('contacts.csv')
print(df)

Импортируем библиотеку, читаем файл и выводим в терминал. Вот, что мы получим в итоге:

06.png


Как видим, библиотека самостоятельно определила, что первая строка является заголовками. А также назначила каждой строке индекс. А теперь проделаем то же самое, что делали в предыдущих примерах, то есть, выведем данные о каждой записи.

В данном случае мы будем итерироваться по значениям, которые представляют из себя список. А также, так как у нас такое же количество заголовков, как и записей в строке, выводим для каждого значения заголовок по индексу, который определяем с помощью enumerate.

Python:
import pandas as pd

df = pd.read_csv('contacts.csv')
for val in df.values:
    for num, item in enumerate(val):
        print(f'{df.columns[num]}: {item}')
    print("\n")

На этом закончим рассматривать способы открытия csv-файлов. За дополнительной документацией по используемым библиотекам можно обратиться к соответствующей документации.

Теперь рассмотрим способы сохранения данных в этот формат.


Сохранение данных в CSV

Предположим у нас есть некий набор данных разделенных запятой. Выглядит это примерно так:

09.png


Этот набор данных необходимо сохранить в csv-файл. Для начала переведем наш набор в список из списков со строками.
Вот, что у нас получиться после перевода:

10.png


После того, как данная операция будет выполнена, откроем файл с расширением «.csv» на запись, укажем кодировку, а также параметр newline='', то есть режим перевода строк. Если не указать данный параметр, строки будут сохранятся не подряд, а разделенные пустой строкой.
Создаем объект писателя, указываем файл, в который нужно записывать значения, а также разделитель. После итерируемся по созданному списку из списков строк и записываем каждый список в файл.

Python:
import csv

data = """Отображаемое имя,Имя,Отчество,Фамилия,Примечание,Номер телефона,Место работы,Должность
Александр Николаевич,Александр,Николаевич,Бочкин,Владеет машиной синего цвета,89056542512,ООО «Рога и копыта»,директор
Василий Васильевич,Василий,Васильевич,Васильев,У него крутой телефон,89078054126,ЗАО «Ноги в руки»,учредитель
Николай Петрович,Николай,Петрович,Бочкин,Отец Александра,89291254556,ОАО «Бегом от инфаркта»,основатель"""

lines = [line.strip().split(",") for line in data.splitlines()]

with open('contacts_write.csv', 'w', encoding='utf-8', newline='') as csvfile:
    writer = csv.writer(csvfile, delimiter=',')
    for row in lines:
        writer.writerow(row)


Сохранение данных в CSV с использованием DictWriter

Также, как и при чтении файлов csv, при записи можно использовать DictWriter. С его помощью можно записать в csv-файл уже готовый словарь с данными. Каждый словарь представляет из себя строку с ключами в виде заголовков. Однако, для начала эти заголовки необходимо определить.

Для начала создадим список со списками, как в предыдущем примере. Так как первая строка в нашем наборе данных представлена заголовками, заберем из списка списков первое значение с помощью pop. pop удаляет значение из списка и возвращает его в переменную. Таким образом, у нас есть список с заголовками. Теперь проитерируемся по списку со списками и создадим с помощью zip словари с данными.

Открываем файл на запись, указываем кодировку, режим перевода строк. Записываем с файл csv заголовки таблицы с помощью DictWriter. Затем итерируемся по созданным словарям из строк и записываем значения в файл.

Python:
import csv

data = """Отображаемое имя,Имя,Отчество,Фамилия,Примечание,Номер телефона,Место работы,Должность
Александр Николаевич,Александр,Николаевич,Бочкин,Владеет машиной синего цвета,89056542512,ООО «Рога и копыта»,директор
Василий Васильевич,Василий,Васильевич,Васильев,У него крутой телефон,89078054126,ЗАО «Ноги в руки»,учредитель
Николай Петрович,Николай,Петрович,Бочкин,Отец Александра,89291254556,ОАО «Бегом от инфаркта»,основатель"""

lines = [line.strip().split(",") for line in data.splitlines()]
headers = lines.pop(0)

dict_lines = [dict(zip(headers, row)) for row in lines]

with open('contacts_write_dict.csv', 'w', encoding='utf-8', newline='') as csvfile:
    writer = csv.DictWriter(
        csvfile,
        delimiter=',',
        fieldnames=headers,
    )
    writer.writeheader()
    for record in dict_lines:
        writer.writerow(record)


Сохранение данных в CSV с помощью Pandas

Также для сохранения данных можно использовать библиотеку pandas. Если она у вас еще не установлена, то ее необходимо установить с помощью pip:

pip install pandas

Как и в предыдущем примере создадим из нашего набора данных список со словарями. После чего, создадим из списка словарей датафрейм, и запишем его в файл с помощью метода to_csv.

Python:
import pandas as pd

data = """Отображаемое имя,Имя,Отчество,Фамилия,Примечание,Номер телефона,Место работы,Должность
Александр Николаевич,Александр,Николаевич,Бочкин,Владеет машиной синего цвета,89056542512,ООО «Рога и копыта»,директор
Василий Васильевич,Василий,Васильевич,Васильев,У него крутой телефон,89078054126,ЗАО «Ноги в руки»,учредитель
Николай Петрович,Николай,Петрович,Бочкин,Отец Александра,89291254556,ОАО «Бегом от инфаркта»,основатель"""

lines = [line.strip().split(",") for line in data.splitlines()]
headers = lines.pop(0)

dict_lines = [dict(zip(headers, row)) for row in lines]
df = pd.DataFrame(dict_lines)
df.to_csv('contacts_write_pandas.csv', index=False)


Сохранение данных в CSV из текстового файла с помощью Pandas

В данном случае, если набор данных не представлен особо сложными структурами, то можно уложиться в одну строку кода, помимо импорта библиотеки.
Здесь мы читаем текстовый файл как csv, а затем сразу же сохраняем его в нужный нам формат с отключенными индексами. Если этого не сделать, в файл, помимо данных, будут сохранены индексы.

07.png


Python:
import pandas as pd

pd.read_csv('contacts.txt').to_csv('contacts_write_pandas_txt.csv', index=False)

Теперь давайте рассмотрим случаи сохранения данных из формата csv в формат xlsx.


Конвертация CSV в XLSX с помощью openpyxl

В данном примере для конвертации данных из одного формата в другой мы будем использовать библиотеку openpyxl.
Следовательно, нам ее необходимо установить, так как, это сторонняя библиотека. Для этого пишем в терминале команду:

pip install openpyxl

Для того, чтобы сохранить данные из формата csv в формат xlsx с помощью данной библиотеки, нам необходимо открыть нужный файл, преобразовать в список списков строк.
Выглядеть на нашем примере это будет так:

12.png


После этого создаем рабочую книгу workbook и делаем ее активной с помощью метода active. Теперь в цикле итерируемся по списку списка строк и добавляем в созданную таблицу.
После окончания итерации сохраняем изменения в файл.

Python:
import csv

import openpyxl

with open("contacts.csv", "r", encoding="utf-8") as file:
    csv_data = [row for row in csv.reader(file)]

workbook = openpyxl.Workbook()
sheet = workbook.active
for row in csv_data:
    sheet.append(row)
workbook.save("contact_openpyxl.xlsx")


Конвертация CSV в Excel с помощью pandas

Рассмотрим еще один пример, в котором будем преобразовывать формат csv в xlsx с помощью библиотеки pandas. Делается это с помощью пары строк. В первой мы открываем файл csv, во второй сохраняем его в xlsx без индексов с созданием заголовков.

Python:
import pandas as pd

file = pd.read_csv('contacts.csv')
file.to_excel('contacts_pandas.xlsx', index=False, header=True)

Ну, а если уж совсем оптимизировать код, то можно записать это в одну строку, помимо импорта:

Python:
import pandas as pd

pd.read_csv('contacts.csv').to_excel('contacts_pandas.xlsx', index=False, header=True)

Однако не забывайте о том, что в будущем, особенно если в вашем коде нет комментариев, такие оптимизированные строки могут затруднить восприятие кода. То есть, работать это будет, но думаю, что выглядит это не совсем «питонически».


Конвертация CSV в Excel с помощью XlsxWriter

Рассмотрим еще один способ, с помощью которого также можно произвести сохранение данных из формата csv в формат xlsx.
Для этого мы будем использовать стороннюю библиотеку xlsxwriter, которую можно установить с помощью данной команды:

pip install XlsxWriter

После того, как библиотека будет установлена, импортируем в скрипт csv, а также Workbook из xlsxwriter.

Создаем файл xlsx. Добавляем в него рабочую книгу. Затем открываем файл csv и в цикле считываем его построчно. Запускаем еще один цикл, в котором итерируемся по столбцу и записываем данные в рабочую книгу по соответствующим индексам координатам. После чего закрываем рабочую книгу.

Python:
import csv

from xlsxwriter.workbook import Workbook

workbook = Workbook('contacts_xlsxwriter.xlsx')
worksheet = workbook.add_worksheet()

with open('contacts.csv', 'r', encoding='utf8') as file:
    for r, row in enumerate(csv.reader(file)):
        for c, col in enumerate(row):
            worksheet.write(r, c, col)
workbook.close()


Конвертация xlsx в csv с помощью openpyxl

Теперь давайте рассмотрим преобразование файлов xlsx в формат csv. Для этого нам понадобиться рассматриваемая ранее библиотека openpyxl.
Поэтому, если вы ее еще не установили, сделать это можно командой:

pip install openpyxl

Импортируем нужные модули в наш скрипт. Загружаем файл xlsx. Делаем активной рабочую книгу. Затем итерируемся по строкам и создаем список из списков строк. А далее, все, как и делали раньше. Открываем файл csv на запись, создаем объект писателя, в который передаем имя файла для записи и разделитель. Итерируемся по списку из списков и записываем в файл.

Python:
import csv

from openpyxl import load_workbook

workbook = load_workbook(filename="contacts_xlsxwriter.xlsx")
sheet = workbook.active
csv_data = [list(value) for value in sheet.iter_rows(values_only=True)]

with open("contacts_openpyxl.csv", 'w', encoding="utf-8", newline='') as file:
    writer = csv.writer(file, delimiter=',')
    for line in csv_data:
        writer.writerow(line)


Конвертация xlsx в csv с помощью pandas

С помощью pandas преобразование происходит довольно просто. Необходимо отрыть файл. А затем сохранить его, указав наличие заголовков и отсутствие индекса.

Python:
import pandas as pd

file = pd.read_excel('contacts_xlsxwriter.xlsx')
file.to_csv('contacts_pandas.csv', index=False, header=True)


Конвертация xls в xlsx с помощью pywin32

Рассмотрим еще один пример, в котором конвертируем файлы формата 2003 офиса в новый xlsx формат. Для этого мы будем использовать библиотеку pywin32, а следовательно, вам требуется, в данном случае, наличие ОС Windows. Для установки библиотеки пишем в терминале:

pip install pywin32

Импортируем нужную нам библиотеку в скрипт. Указываем путь к конвертируемому файлу. Обратите внимание, что вы должны указать абсолютный путь. Явно или с помощью других библиотек. Создаем объект 'Excel.Application', открываем файл. Ну, а далее, сохраняем его с добавлением одной буквы к расширению и с указанием сохраняемого формата. В нашем случае FileFormat указан 51, что соответствует файлу xlsx. 56 – соотсетствует xls. После чего закрываем исходный файл и выходим из приложения.

Python:
import win32com.client as win32

file = r"D:\python\csv_rw\contacts_pandas.xls"
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(file)

wb.SaveAs(f'{file}x', FileFormat=51)
wb.Close()
excel.Application.Quit()


Подведем небольшие итоги

В данной статье мы рассмотрели различные способы открытия, сохранения, а также конвертации файлов в формате csv. Конечно же, это самые простые случаи, но на их основе уже можно составить представление о том, как строить свою работу и какую информацию искать в дальнейшем.

Для более подробной информации можно обратиться к документации:

А на этом, пожалуй, все.

Спасибо за внимание. Надеюсь, данная информация будет вам полезна
 

Вложения

  • source.zip
    10,6 КБ · Просмотры: 70
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!