Когда скрипт удобнее веб-интерфейса
- Список содержит десятки тысяч строк, и вставка в браузер неудобна или ограничена.
- Обработка должна повторяться регулярно — например, при каждой выгрузке каталога.
- Результат нужно сразу встроить в автоматизированный процесс — импорт в базу, генерацию файла для CMS.
- Исходные данные содержат коммерческую информацию, которую нежелательно передавать куда-либо за пределы локальной среды.
Скрипт на Python для обработки CSV
import csv, re
MAP = {
'а':'a','б':'b','в':'v','г':'g','д':'d','е':'e','ё':'e','ж':'zh',
'з':'z','и':'i','й':'j','к':'k','л':'l','м':'m','н':'n','о':'o',
'п':'p','р':'r','с':'s','т':'t','у':'u','ф':'f','х':'h','ц':'c',
'ч':'ch','ш':'sh','щ':'shh','ъ':'','ы':'y','ь':'','э':'e',
'ю':'yu','я':'ya',
}
def translit(text, sep='-'):
text = ''.join(MAP.get(ch, ch) for ch in str(text).lower())
text = re.sub('[^a-z0-9]+', sep, text)
return text.strip(sep)
with open('catalog.csv', encoding='utf-8') as src, \
open('catalog-with-urls.csv', 'w', encoding='utf-8', newline='') as dst:
reader = csv.DictReader(src)
writer = csv.DictWriter(dst, fieldnames=reader.fieldnames + ['url'])
writer.writeheader()
for row in reader:
row['url'] = translit(row['name'])
writer.writerow(row)
Функция транслитерации здесь та же, что подробно разобрана в статье про функцию транслита на PHP, JavaScript и Python — скрипт просто оборачивает её в чтение и запись CSV-файла построчно.
Скрипт на Node.js для обработки JSON
const fs = require('fs');
const MAP = {
а:'a', б:'b', в:'v', г:'g', д:'d', е:'e', ё:'e', ж:'zh', з:'z',
и:'i', й:'j', к:'k', л:'l', м:'m', н:'n', о:'o', п:'p', р:'r',
с:'s', т:'t', у:'u', ф:'f', х:'h', ц:'c', ч:'ch', ш:'sh',
щ:'shh', ъ:'', ы:'y', ь:'', э:'e', ю:'yu', я:'ya'
};
function translit(text, sep = '-') {
return String(text).toLowerCase().split('')
.map(ch => (ch in MAP ? MAP[ch] : ch)).join('')
.replace(/[^a-z0-9]+/g, sep)
.replace(/^-+|-+$/g, '');
}
const items = JSON.parse(fs.readFileSync('catalog.json', 'utf8'));
const result = items.map(item => ({ ...item, url: translit(item.name) }));
fs.writeFileSync('catalog-with-urls.json', JSON.stringify(result, null, 2));
Проверка уникальности после массовой генерации. Скрипт транслитерации сам по себе не проверяет, не совпал ли новый адрес с уже существующим. После обработки всего файла отдельным шагом стоит проверить список результатов на повторы — точно так же, как это описано в общей проверке каталога в статье про адрес карточки товара.
Проверка дублей в результате скриптом
import csv
from collections import Counter
with open('catalog-with-urls.csv', encoding='utf-8') as f:
urls = [row['url'] for row in csv.DictReader(f)]
duplicates = [url for url, count in Counter(urls).items() if count > 1]
print(f'Найдено повторов: {len(duplicates)}')
for url in duplicates[:20]:
print(' ', url)
Запуск по расписанию
Если обработка должна повторяться регулярно — например, после каждой ночной выгрузки каталога, — скрипт можно запускать автоматически через планировщик задач операционной системы, без участия человека. Логику проверки уникальности при этом стоит встроить в сам скрипт, чтобы отчёт о повторах приходил сразу вместе с результатом, а не требовал отдельного запуска.
Чек-лист
- Использовать скрипт вместо веб-интерфейса для файлов от нескольких тысяч строк.
- Держать таблицу транслитерации в скрипте синхронизированной с той, что используется на самом сайте.
- Проверять результат на дубли отдельным шагом после обработки.
- Для регулярных задач — встраивать скрипт в автоматический процесс выгрузки.
Обработка файлов, не помещающихся в память целиком
Для каталогов в сотни тысяч и миллионы строк построчное чтение файла вместо загрузки его целиком в память становится обязательным приёмом. Оба приведённых выше скрипта уже читают файл построчно через стандартные механизмы csv.DictReader в Python и построчное чтение в Node.js, поэтому такие объёмы они обрабатывают без модификации логики, только с ростом времени выполнения.
Параллельная обработка для ускорения
Если обработка миллионов строк требуется регулярно и укладывается в жёсткие временные рамки, скрипт можно распараллелить, разбив исходный файл на части и запустив несколько процессов одновременно, а затем объединив результаты. Для большинства каталогов интернет-магазинов, редко превышающих сотню тысяч позиций, в этом нет необходимости — обычный последовательный скрипт справляется за секунды.
Частые вопросы
Когда стоит писать скрипт вместо использования онлайн-генератора?
Когда список содержит десятки тысяч строк, обработка повторяется регулярно, или данные не должны покидать локальную среду. Для разовой задачи на несколько сотен строк веб-интерфейс обычно удобнее.
Проверяет ли скрипт транслитерации уникальность полученных адресов?
Нет, сама функция транслитерации об этом не знает. Проверку на дубли нужно делать отдельным шагом после массовой обработки — например, скриптом, подсчитывающим повторяющиеся значения.
Можно ли использовать один и тот же скрипт для регулярных обновлений каталога?
Да, скрипт можно запускать по расписанию через планировщик задач, встроив в него и генерацию адресов, и проверку на дубли, чтобы результат обрабатывался полностью автоматически.
Готовый адрес можно собрать прямо сейчас: откройте генератор ЧПУ — он транслитерирует фразу по таблице Яндекса, уберёт служебные слова и покажет длину адреса.