Парсинг сайтов поставщиков и загрузка цен в 1С: готовый код
Автоматическая загрузка прайс-листов избавляет менеджеров от ручного копирования цен, артикулов и остатков. Если поставщик не предоставляет удобный API, данные можно получать непосредственно со страницы каталога или из файла, который формируется на его сайте.
Для 1С:Предприятия важно разделять получение HTML, извлечение реквизитов товара, сопоставление с номенклатурой и запись цен. Такая схема упрощает отладку и позволяет заменить источник данных без переделки всей обработки.
Ниже приведен рабочий каркас внешней обработки на встроенном языке 1С. Он рассчитан на HTML-разметку с блоками товаров, но легко адаптируется под XML, JSON, CSV или прайс-лист Excel.
Как организовать загрузку данных
Обработка обычно состоит из четырех этапов: соединение с сайтом, получение страницы, разбор карточек и запись результата в табличную часть документа установки цен. До загрузки в базу желательно сохранить исходный ответ сервера: это помогает понять, изменилась ли верстка или возникла ошибка авторизации.
В примере ниже используются маркеры HTML. Предполагается, что товар описан блоком <div class="product">, артикул находится в атрибуте data-sku, а цена — внутри элемента <span class="price">. Эти фрагменты нужно заменить на реальные признаки страницы поставщика.
Перед тестированием обработки полезно проверить разбор на отдельном HTML-файле или тестовой странице с текстом, чтобы исключить влияние авторизации и сетевых ограничений.
Готовый код обработки на 1С
Функция ниже получает каталог и формирует таблицу значений. В рабочей конфигурации результат можно передать в документ «Установка цен номенклатуры» или записать во временное хранилище для последующего сопоставления.
Функция ПолучитьМежду(Текст, МаркерНачала, МаркерКонца, Позиция = 0) Экспорт
Начало = СтрНайти(Текст, МаркерНачала, Позиция);
Если Начало = 0 Тогда
Возврат Новый Структура("Значение,Позиция", "", 0);
КонецЕсли;
Начало = Начало + СтрДлина(МаркерНачала);
Конец = СтрНайти(Текст, МаркерКонца, Начало);
Если Конец = 0 Тогда
Возврат Новый Структура("Значение,Позиция", "", 0);
КонецЕсли;
Значение = Сред(Текст, Начало, Конец - Начало);
Значение = СокрЛП(Значение);
Возврат Новый Структура(
"Значение,Позиция",
Значение,
Конец + СтрДлина(МаркерКонца));
КонецФункции
Функция ЗагрузитьЦеныПоставщика(АдресСервера, ПутьКаталога) Экспорт
Соединение = Новый HTTPСоединение(АдресСервера, , , , , 30, Истина);
Запрос = Новый HTTPЗапрос(ПутьКаталога);
Запрос.Заголовки.Вставить("User-Agent", "1C Price Loader/1.0");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния <> 200 Тогда
ВызватьИсключение "Сайт вернул код " + Ответ.КодСостояния;
КонецЕсли;
HTML = Ответ.ПолучитьТелоКакСтроку();
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Артикул");
Результат.Колонки.Добавить("Цена");
Позиция = 0;
Пока Истина Цикл
Блок = ПолучитьМежду(HTML, "<div class=""product"">", "</div>", Позиция);
Если Блок.Позиция = 0 Тогда
Прервать;
КонецЕсли;
Артикул = ПолучитьМежду(Блок.Значение, "data-sku=""", """").Значение;
ЦенаТекст = ПолучитьМежду(
Блок.Значение,
"<span class=""price"">",
"</span>").Значение;
ЦенаТекст = СтрЗаменить(ЦенаТекст, "руб.", "");
ЦенаТекст = СтрЗаменить(ЦенаТекст, " ", "");
ЦенаТекст = СтрЗаменить(ЦенаТекст, Символы.НПП, "");
ЦенаТекст = СтрЗаменить(ЦенаТекст, ",", ".");
Если ЗначениеЗаполнено(Артикул)
И ЗначениеЗаполнено(ЦенаТекст) Тогда
НоваяСтрока = Результат.Добавить();
НоваяСтрока.Артикул = Артикул;
НоваяСтрока.Цена = Число(ЦенаТекст);
КонецЕсли;
Позиция = Блок.Позиция;
КонецЦикла;
Возврат Результат;
КонецФункции
Код намеренно не содержит привязки к конкретному справочнику. После получения таблицы нужно найти номенклатуру по артикулу или коду поставщика, определить тип цены и создать строки документа. Если товар не найден, его лучше помещать в отдельный список, а не создавать автоматически без контроля.
Что проверить перед запуском
Парсер ломается не из-за самого HTTP-запроса, а из-за различий между ожидаемой и фактической страницей. Сначала откройте исходный код сайта, найдите повторяющийся блок товара и убедитесь, что цена действительно передается в HTML. Если данные появляются только после выполнения JavaScript, потребуется API, Selenium-подобный сервис или экспортный файл.
Полезно заранее определить правила обработки служебных значений. Например, цена может содержать валюту, скидку, разделитель тысяч, пометку «по запросу» или несколько вариантов упаковки.
- проверить код ответа и кодировку страницы;
- определить уникальный ключ товара у поставщика;
- зафиксировать формат цены и валюту;
- выяснить ограничения по частоте запросов;
- сохранить пример исходного HTML для регрессионного теста.
Как избежать неверной загрузки цен
Сопоставление по наименованию считается резервным вариантом: одинаковые товары могут называться по-разному, а похожие позиции — иметь почти одинаковое описание. Надежнее использовать артикул, штрихкод или отдельный регистр соответствий «Код поставщика — Номенклатура».
Перед записью цен стоит сравнить новую стоимость с предыдущей. Резкое изменение, нулевая цена или пропавший товар требуют ручной проверки. Для крупных каталогов обработку запускают порциями и фиксируют дату, источник и результат каждой загрузки.
- запрещать запись отрицательных и нулевых цен;
- проверять максимально допустимое изменение стоимости;
- вести журнал найденных и пропущенных товаров;
- не удалять старые цены при временной ошибке сайта;
- сохранять идентификатор запуска обработки.
Интеграция с документами 1С
После сопоставления создается документ установки цен с видом цены, валютой, периодом действия и ответственным пользователем. Если в базе уже есть механизм загрузки из Excel, таблицу значений можно передать в его общую процедуру и повторно использовать штатные проверки.
Для регулярного обмена подойдет регламентное задание. В нем задаются расписание, учетная запись поставщика, каталог загрузки и уведомление об ошибках. Пароли нельзя хранить в открытом виде в коде обработки: используйте безопасное хранилище настроек или защищенные параметры информационной базы.
При большом количестве поставщиков практично вынести настройки в справочник: адрес, формат данных, маркеры HTML, вид цены, правило округления и соответствие валют. Тогда добавление нового источника сводится к заполнению карточки, а не к копированию программного кода.
Контроль результата и сопровождение
Работу загрузчика следует оценивать по отчету, а не только по отсутствию исключения. Успешный HTTP-ответ еще не означает, что в страницу попали товары: сайт может показать форму входа, сообщение о блокировке или пустой каталог.
Минимальный отчет должен показывать количество полученных карточек, найденных соответствий, обновленных цен и пропущенных строк. При изменении верстки администратор сразу увидит отклонение от обычной статистики.
- количество товаров в ответе поставщика;
- число сопоставленных позиций;
- список новых артикулов;
- товары с некорректной ценой;
- текст и время последней ошибки.
Разумно ограничить частоту обращений к сайту и использовать задержки между страницами. Это снижает риск блокировки и нагрузку на сервер поставщика. Для стабильной эксплуатации также нужны тайм-аут, повтор запроса и уведомление ответственному сотруднику.
Готовую обработку можно разместить в общей библиотеке предприятия, связать с регламентным заданием и дополнить формой ручного запуска. Для обсуждения вариантов реализации, обмена примерами кода и поиска решений для конкретной конфигурации используйте вход на форум 1С.