Чтение и очистка выгрузки из CRM: короткое руководство
За 15–20 минут вы проверите CSV-выгрузку CRM, приведёте пробелы и адреса почты к единому виду и сохраните результат в отдельный файл. Исходник останется нетронутым, а возможные дубли вы сможете проверить вручную.

За 15–20 минут вы проверите CSV-выгрузку CRM, нормализуете пробелы и адреса почты, а результат сохраните в новый файл. Исходник останется нетронутым; записи с повторяющимся email скрипт пометит для проверки, но не удалит автоматически.
Что понадобится
Пример рассчитан на Python 3.12 и стандартную библиотеку: устанавливать сторонние пакеты не нужно. Нужен CSV-файл с заголовками name, email и phone. В коде ниже также есть необязательное поле company. Если ваша CRM называет столбцы иначе, замените эти имена в списке required_columns и в обработке полей.
Скачайте выгрузку в CSV и положите копию в отдельную папку. В примере ожидается разделитель «;» — частый вариант для табличных выгрузок с региональными настройками. Если в вашем файле столбцы разделены запятыми, поменяйте значение delimiter в коде на запятую. CSV — текстовый формат с разделителями: кавычки позволяют сохранить разделитель внутри значения ячейки.1
Не отправляйте выгрузку с клиентскими контактами в онлайн-конвертеры и не публикуйте её в открытых репозиториях. В ней могут быть персональные и коммерчески чувствительные данные.
Подготовьте скрипт
- Сохраните исходную выгрузку под именем
crm_export.csvрядом с будущим скриптом. Проверьте, что заголовки действительно содержат поля для имени, email и телефона. Проверка: файл открывается локально, первая строка — заголовки, а не данные. - Создайте файл
clean_crm.pyи вставьте код ниже целиком. Он читает UTF-8 с возможной BOM в начале файла, очищает пробелы, приводит email к нижнему регистру и добавляет отметку о повторяющемся email. Проверка: в скрипте нет пропусков вроде «добавьте остальное здесь». - Откройте терминал в папке с обоими файлами и выполните
python --version. Проверка: команда сообщает Python 3.12. Если у вас несколько версий Python, вызывайте нужную установленную версию явно.
Код предназначен для Python 3.12; используются только модули стандартной библиотеки.
import csv
import re
INPUT_FILE = "crm_export.csv"
OUTPUT_FILE = "crm_cleaned.csv"
DELIMITER = ";"
required_columns = {"name", "email", "phone"}
seen_emails = set()
row_count = 0
blank_email_count = 0
repeat_email_count = 0
with open(INPUT_FILE, "r", encoding="utf-8-sig", newline="") as source:
reader = csv.DictReader(source, delimiter=DELIMITER)
if reader.fieldnames is None:
raise ValueError("В файле не найдена строка заголовков")
reader.fieldnames = [name.strip() for name in reader.fieldnames]
missing_columns = required_columns - set(reader.fieldnames)
if missing_columns:
raise ValueError(
"Не найдены обязательные столбцы: " + ", ".join(sorted(missing_columns))
)
output_columns = reader.fieldnames + ["duplicate_email"]
with open(OUTPUT_FILE, "w", encoding="utf-8-sig", newline="") as target:
writer = csv.DictWriter(
target,
fieldnames=output_columns,
delimiter=DELIMITER,
extrasaction="ignore",
)
writer.writeheader()
for row in reader:
if None in row:
raise ValueError(
f"Строка {reader.line_num}: полей больше, чем заголовков"
)
cleaned = {}
for column in reader.fieldnames:
value = row.get(column) or ""
value = re.sub(r"\s+", " ", value).strip()
if column == "email":
value = value.lower()
cleaned[column] = value
email = cleaned.get("email", "")
duplicate_email = ""
if not email:
blank_email_count += 1
elif email in seen_emails:
duplicate_email = "check"
repeat_email_count += 1
else:
seen_emails.add(email)
cleaned["duplicate_email"] = duplicate_email
writer.writerow(cleaned)
row_count += 1
print(f"Записей обработано: {row_count}")
print(f"Пустых email: {blank_email_count}")
print(f"Повторных email для проверки: {repeat_email_count}")
print(f"Результат: {OUTPUT_FILE}")
Запустите и проверьте результат
- Запустите
python clean_crm.py. Скрипт создастcrm_cleaned.csv, не перезаписывая исходную выгрузку. Проверка: в терминале появились счётчики обработанных записей и имя выходного файла. - Откройте результат в табличном редакторе и сравните число строк с исходником. Проверка: у каждой исходной записи осталась строка, а справа появился столбец
duplicate_email. - Отфильтруйте отметки
checkи проверьте эти записи по CRM. Проверка: вы решили для каждой пары, действительно ли это один контакт, а не общий адрес компании или семьи. - Перед импортом результата в CRM проверьте на нескольких строках имя, телефон и email, включая значения с кавычками, пробелами и разделителем внутри поля. Проверка: данные не переехали в соседние столбцы и не потеряли значимые символы.
Что скрипт меняет — и чего не делает
Убираются пробелы по краям полей и сводятся последовательности пробельных символов к одному пробелу. Email обрезается по краям и переводится в нижний регистр. Остальные символы телефона сохраняются: код не угадывает страну, не удаляет добавочные номера и не превращает все записи в один международный формат.
Повторный email помечается, но строка остаётся в файле. Это важно: совпадение не доказывает, что контакты можно объединить. Один адрес может быть общим, а запись без email вообще может оказаться полноценным клиентом. Автоматическое удаление дублей способно потерять историю сделок и обращения.
Очистка должна делать данные единообразнее, а не решать за вас, какие записи можно выбросить. Сначала помечайте сомнительное, затем сверяйте с CRM и только после этого объединяйте.
Термин: BOM. Это служебная метка в начале текстового файла. Некоторые программы добавляют её при сохранении UTF-8; чтение с utf-8-sig помогает убрать её из первого заголовка, чтобы скрипт видел ожидаемое имя столбца.
Если не получилось
- «Не найдены обязательные столбцы». Заголовки в выгрузке отличаются от
name,emailилиphone. Посмотрите первую строку CSV и замените имена в коде. Проверьте также, что в файле есть заголовки. - «Строка …: полей больше, чем заголовков». В одной из строк больше значений, чем названий столбцов. Частая причина — неэкранированный разделитель внутри ячейки или неверно выбранный
DELIMITER. Исправьте экспорт или проверьте разделитель в текстовом редакторе. - Вся строка попала в один столбец. Обычно выбран не тот разделитель. Если файл разделяет поля запятыми, задайте
DELIMITER = ","; если точкой с запятой — оставьте";". Проверка: после повторного запуска значения разложились по отдельным столбцам. - Появились нечитаемые символы. Выгрузка может быть не в UTF-8. Повторно экспортируйте файл в UTF-8 из CRM или табличного редактора. Не подбирайте кодировку наугад для единственной копии: сначала сохраните оригинал.
- Скрипт не запускается командой
python. Python может отсутствовать или команда может указывать на другую установку. Проверьте установленную версию и используйте соответствующий запускатель вашей системы; синтаксис самого скрипта рассчитан на Python 3.12.
Что делать дальше
Сначала проверьте результат на небольшой копии выгрузки, затем сравните количество строк, пустых значений и повторных адресов с исходными цифрами CRM. Если дальше планируете импорт, протестируйте его на нескольких записях и убедитесь, что CRM не создаёт новые контакты вместо обновления существующих. Нормализация телефонов, проверка корректности адресов и объединение дублей — отдельные задачи; правила для них зависят от данных и настроек вашей CRM.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Документация Python 3.12: модуль csv
Частые вопросы
Можно ли запускать скрипт на выгрузке с запятыми вместо точки с запятой?
Скрипт удалит повторные контакты?
Что делать, если в CRM другие названия столбцов?
Почему телефоны остаются в разных форматах?
Можно ли сразу импортировать очищенный файл обратно в CRM?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.