При разработке интеграций и парсинге сторонних интернет-магазинов или веб-сервисов разработчики 1С часто сталкиваются с ситуацией, когда на самом сайте отображаются актуальные цены и остатки, а при загрузке страницы в 1С вместо реальной стоимости считывается значение «100 р.» или пустая строка. Рассмотрим, почему возникает эта проблема и как правильно организовать парсинг данных в 1С.
Выясним причину такого поведения платформы. Объекты 1С HTTPСоединение, HTTPЗапрос, а также ЧтениеHTML и ПостроительDOM работают исключительно с сетевым HTTP-ответом и статическим HTML-кодом. Они не имеют встроенного движка выполнения скриптов (JavaScript).
Многие современные сайты используют клиентский рендеринг (Single Page Applications или библиотеки jQuery/React/Vue). При отправке обычного GET-запроса сервер возвращает каркас страницы, в котором подставлены базовые значения-заглушки (например, «100 р.» в таблице по умолчанию). Затем браузер пользователя выполняет встроенный сценарий JavaScript, делает дополнительный запрос (AJAX/Fetch) к внутреннему API и подставляет настоящую цену в DOM-дерево. Поскольку встроенные средства HTTP-запросов 1С не исполняют JS, они получают только первичный шаблон страницы.
Разберем пример кода, в котором попытка разобрать DOM-дерево HTML-страницы приводит к считыванию статических заглушек:
&НаКлиенте
Функция ПолучитьСтраницуВОбъектDOM(Знач Адрес)
АдресСтруктура = СтруктураАдреса(Адрес);
Соединение = Новый HTTPСоединение(АдресСтруктура.ИмяСервера, АдресСтруктура.Порт);
ВебЗапрос = Новый HTTPЗапрос(АдресСтруктура.ПутьНаСервере);
Попытка
Результат = Соединение.Получить(ВебЗапрос);
Исключение
Сообщить("Ошибка соединения");
ВызватьИсключение;
КонецПопытки;
Ответ = Результат.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Чтение = Новый ЧтениеHTML;
Чтение.УстановитьСтроку(Ответ);
ОбъектыDOM = Новый ПостроительDOM;
Возврат ОбъектыDOM.Прочитать(Чтение);
КонецФункции
При обработке полученного объекта DOMDocument поиск элементов по тегам tbody или tr вернет только первичные статичные теги, сформированные до работы скриптов.
Для получения реальных данных проанализируем структуру ответа сервера или исходный текст страницы. В большинстве случаев данные товаров передаются в виде массива объектов JSON — либо внутри тега script в теле страницы, либо отдельным AJAX-запросом.
Посмотрим на пример извлечения данных из тела ответа с помощью HTTP-запроса или объекта COM MSXML2.XMLHTTP:
WinHttp = Новый COMОбъект("MSXML2.XMLHTTP.6.0");
WinHttp.Open("GET", "https://example.com/catalog/item_id", Ложь);
WinHttp.Send();
ТекстОтвета = WinHttp.ResponseText;
В тексте ответа находится не только HTML, но и блок с данными вида:
data: [{"IdStore":"13325","Region":"Челябинск","Cat":"Vag","Name":"ГЕНЕРАТОР","Price":18715.01,"Days":19}, ...]
Найти и Сред).ЧтениеJSON и ПрочитатьJSON().Price напрямую из полученной структуры 1С.Рассмотрим пример кода на стороне 1С для работы со встроенными средствами HTTPСоединение и разбором JSON:
&НаСервере
Функция ПолучитьАктуальныеЦеныССайта(ИмяСервера, ПутьНаСервере)
Соединение = Новый HTTPСоединение(ИмяСервера, 443, , , , 10, Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(ПутьНаСервере);
// Передаем необходимые заголовки для имитации браузера
Запрос.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
Запрос.Заголовки.Вставить("X-Requested-With", "XMLHttpRequest");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Извлекаем JSON-строку из текста ответа
ПозицияНачала = Найти(ТекстОтвета, "data: [");
Если ПозицияНачала > 0 Тогда
СтрокаJSON = Сред(ТекстОтвета, ПозицияНачала + 6);
ПозицияКонца = Найти(СтрокаJSON, "]}");
Если ПозицияКонца > 0 Тогда
СтрокаJSON = Лев(СтрокаJSON, ПозицияКонца + 1);
// Читаем JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
МассивТоваров = ПрочитатьJSON(ЧтениеJSON);
Возврат МассивТоваров;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Если данные подгружаются отдельным внутренним API-эндопоинтом (XHR), рекомендуется изучить сетевые запросы страницы в консоли разработчика браузера (вкладка Network / Сеть). Направив HTTPЗапрос непосредственно на URL этого API, вы получите чистый JSON с ценами без необходимости распарсивать HTML-документ.
В случаях, когда сайт требует полноценной эмуляции браузера для генерации сессионных ключей на JS, на клиентской стороне 1С можно использовать элемент формы ПолеHTMLДокумента, который выполняет JS-скрипты, после чего извлекать итоговый DOM из объекта документа Элементы.ПолеHTML.Документ.