Загрузка данных
import csv
import re
import json
def split_description_and_characteristics(text):
"""Разделяет смешанные описание и характеристики"""
if not text:
return '', ''
# Ищем паттерн характеристик в тексте
# Характеристики обычно выглядят как [["ключ","значение"],...] или [["ключ", "значение"]]
char_pattern = r'(\[\s*\["[^"]*",\s*"[^"]*"\]\s*(?:,\s*\["[^"]*",\s*"[^"]*"\])*\s*\])'
match = re.search(char_pattern, text)
if match:
# Нашли характеристики
chars_str = match.group(1)
# Всё, что до характеристик - это описание
description = text[:match.start()].strip()
# Всё, что после характеристик - это мусор (нумерация и т.д.)
# Удаляем цифры с точкой в конце
description = re.sub(r'\d+\.\s*$', '', description)
description = re.sub(r'\s+', ' ', description).strip()
# Парсим характеристики в нормальный JSON
try:
chars = json.loads(chars_str)
except:
# Если не парсится, пытаемся извлечь пары
chars = []
pattern = r'\["([^"]*)",\s*"([^"]*)"\]'
matches = re.findall(pattern, chars_str)
for key, value in matches:
chars.append([key, value])
return description, json.dumps(chars, ensure_ascii=False)
else:
# Нет характеристик в тексте
# Проверяем, может быть текст заканчивается на [] или ['']?
if text.strip().endswith('[]') or text.strip().endswith("['']"):
# Убираем пустые характеристики
text = text.replace('[]', '').replace("['']", '').strip()
# Удаляем нумерацию
text = re.sub(r'\d+\.\s*$', '', text)
text = re.sub(r'\s+', ' ', text).strip()
return text, '[]'
else:
# Просто очищаем описание
text = re.sub(r'\d+\.\s*$', '', text)
text = re.sub(r'\s+', ' ', text).strip()
return text, '[]'
def process_csv(input_file, output_file):
"""Обрабатывает CSV файл и разделяет описание и характеристики"""
with open(input_file, 'r', encoding='utf-8') as infile:
# Читаем первую строку как заголовки
header = infile.readline().strip().split(';')
# Очищаем заголовки от кавычек
header = [h.strip('"') for h in header]
rows = []
for line in infile:
# Разбиваем строку с учетом кавычек
reader = csv.reader([line], delimiter=';', quotechar='"')
row = next(reader)
# Проверяем, что у нас правильное количество колонок
while len(row) < len(header):
row.append('')
# Обрабатываем каждое поле
processed_row = []
description = ''
characteristics = ''
for i, value in enumerate(row):
# Удаляем лишние кавычки с начала и конца
value = value.strip('"')
if header[i] == 'description':
# Здесь может быть смесь описания и характеристик
description, characteristics = split_description_and_characteristics(value)
# В description записываем очищенное описание
processed_row.append(description)
elif header[i] == 'h':
# Если в h уже есть характеристики, используем их
# Или если характеристики были в description, они уже извлечены
if value and value.strip() not in ['[]', "['']"]:
# Парсим существующие характеристики
chars = parse_characteristics(value)
if chars:
processed_row.append(json.dumps(chars, ensure_ascii=False))
else:
processed_row.append('[]')
else:
# Используем характеристики из description, если они там были
processed_row.append(characteristics)
elif header[i] == 'images':
# Проверяем, что путь к картинке корректен
if value and not value.startswith('..'):
value = '../assets/img/' + value
processed_row.append(value)
elif header[i] == 'price':
# Приводим цену к единому формату
try:
price = float(value)
value = f"{price:.2f}"
except ValueError:
pass
processed_row.append(value)
elif header[i] == 'quantity':
# Приводим количество к целому числу
try:
value = str(int(float(value)))
except ValueError:
value = '0'
processed_row.append(value)
else:
processed_row.append(value)
rows.append(processed_row)
# Записываем обработанные данные в новый файл
with open(output_file, 'w', encoding='utf-8', newline='') as outfile:
writer = csv.writer(outfile, delimiter=';', quotechar='"', quoting=csv.QUOTE_ALL)
# Записываем заголовки
writer.writerow(header)
# Записываем данные
for row in rows:
writer.writerow(row)
print(f"Файл успешно обработан и сохранен как {output_file}")
def parse_characteristics(h_string):
"""Парсит строку характеристик в нормальный JSON"""
if not h_string or h_string.strip() in ['[]', "['']"]:
return []
try:
# Пробуем распарсить как JSON
chars = json.loads(h_string)
return chars
except json.JSONDecodeError:
# Если не JSON, пытаемся извлечь данные
chars = []
# Ищем пары в формате ["ключ", "значение"]
pattern = r'\["([^"]*)",\s*"([^"]*)"\]'
matches = re.findall(pattern, h_string)
if matches:
for key, value in matches:
chars.append([key, value])
return chars
# Использование скрипта
if __name__ == "__main__":
input_file = "products.csv" # имя вашего исходного файла
output_file = "products_cleaned.csv" # имя обработанного файла
process_csv(input_file, output_file)