Как разобрать и распарсить HTML в 1С:Предприятие

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними сайтами, парсинге каталогов поставщиков или получении данных с веб-страниц разработчики часто сталкиваются с необходимостью извлечь нужную информацию из HTML-разметки. Разберем основные способы решения этой задачи, начиная со штатных средств платформы и заканчивая специализированными альтернативными подходами.

Вариант 1. Использование штатных объектов ЧтениеHTML и ПостроительDOM

Платформа 1С:Предприятие предоставляет встроенные инструменты для чтения и синтаксического анализа разметки: объекты ЧтениеHTML и ПостроительDOM. Они позволяют преобразовать веб-страницу в объектную модель документа (DOM) и работать с ней программно.

Рассмотрим базовый пример создания DOM-дерева из веб-страницы:


ЧтениеHTML = Новый ЧтениеHTML;
ПостроительDOM = Новый ПостроительDOM;

ЧтениеHTML.ОткрытьФайл("http://forum.mista.ru", "windows-1251");
ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);

Однако на практике метод ОткрытьФайл с передачей прямого URL имеет серьезные ограничения: он не позволяет передать заголовки запроса (например, User-Agent, авторизационные куки или заголовки сжатия). Из-за этого многие современные веб-серверы блокируют подобные запросы или отдают страницу с ошибкой.

Разберем по шагам более надежный и правильный подход, в котором загрузка данных и их последующий разбор разделены:

  1. Скачиваем содержимое страницы с помощью объекта HTTPСоединение и настраиваемого HTTPЗапрос.
  2. Передаем полученный текст ответа в ЧтениеHTML через метод УстановитьСтроку().
  3. Формируем объект ДокументHTML с помощью объекта ПостроительDOM.

Посмотрим на практический пример реализации:


Соединение = Новый HTTPСоединение("site.example.com", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL);
ЗапросHTTP = Новый HTTPЗапрос("/catalog/items");
ЗапросHTTP.Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

ОтветHTTP = Соединение.Получить(ЗапросHTTP);

Если ОтветHTTP.КодСостояния = 200 Тогда
    ТекстHTML = ОтветHTTP.ПолучитьТелоКакСтроку();
    
    ПарсерHTML = Новый ЧтениеHTML;
    ПарсерHTML.УстановитьСтроку(ТекстHTML);
    
    Построитель = Новый ПостроительDOM;
    ДокументDOM = Построитель.Прочитать(ПарсерHTML);
    
    // Получаем доступ к тегам страницы
    Элементы = ДокументDOM.ПолучитьЭлементыПоИмениТега("div");
    Для Каждого Элемент Из Элементы Цикл
        // Обработка узлов DOM
    КонецЦикла;
    
    ПарсерHTML.Закрыть();
КонецЕсли;

Важное ограничение: штатный ПостроительDOM крайне чувствителен к валидности кода. Если на странице присутствуют незакрытые теги, грубые синтаксические ошибки или некорректная вложенность, метод Прочитать() может вызвать исключение.

Вариант 2. Выборка данных с помощью XPath

Когда документ успешно прочитан в объект ДокументHTML, искать нужные элементы последовательным перебором циклом не всегда удобно. Платформа поддерживает язык запросов XPath, который позволяет адресовать конкретные узлы документа по их атрибутам, структуре или пути.

Для работы с XPath используются объекты ВыражениеXPath и РазыменовательПространствИменDOM. Проанализируем пример получения таблицы с заданным классом:


Разыменователь = ДокументDOM.СоздатьРазыменовательПространствИмен(ДокументDOM.ЭлементДокумента);
Выражение = ДокументDOM.СоздатьВыражениеXPath("//table[@class='price-table']//tr", Разыменователь);

РезультатXPath = Выражение.Вычислить(ДокументDOM, ТипРезультатаXPath.НеупорядоченныйНаборУзлов);
Узел = РезультатXPath.ПолучитьСледующий();

Пока Узел <> Неопределено Цикл
    ТекстСтроки = Узел.ТекстовоеСодержимое;
    Узел = РезультатXPath.ПолучитьСледующий();
КонецЦикла;

Этот подход значительно ускоряет выборку данных со сложных страниц с глубокой вложенностью элементов.

Вариант 3. Использование COM-объекта htmlfile (только для Windows)

Если страница содержит невалидную HTML-разметку, штатный ПостроительDOM не сможет ее обработать. В операционных системах семейства Windows отличным решением является COM-объект htmlfile (движок MSHTML). Его ключевое преимущество заключается в том, что он автоматически исправляет ошибки синтаксиса и строит корректное дерево документа.

Рассмотрим пример загрузки и обработки строки с помощью htmlfile:


HTMLДокумент = Новый COMОбъект("htmlfile");
HTMLДокумент.open();
HTMLДокумент.write(ТекстHTML);
HTMLДокумент.close();

// Поиск элементов по тегу или классу
ВсеТаблицы = HTMLДокумент.getElementsByTagName("table");
Для Счетчик = 0 По ВсеТаблицы.length - 1 Цикл
    Таблица = ВсеТаблицы.item(Счетчик);
    // Извлечение нужных данных
КонецЦикла;

Обратите внимание: данный способ работает исключительно на серверах и клиентах под управлением Windows и не может использоваться на серверах под Linux.

Вариант 4. Разбор с помощью регулярных выражений или строковых функций

Если с веб-страницы требуется получить всего одно или два значения (например, номер заказа, CSRF-токен, артикул или цену товара), построение полного DOM-дерева избыточно и ресурсоемко. В таких ситуациях эффективно применить строковые функции платформы (Найти, Сред, СтрШаблон) или регулярные выражения.

В современных версиях платформы реализован встроенный объект РегулярноеВыражение:


Выражение = Новый РегулярноеВыражение("<span class=""price"">(.*?)</span>");
Результат = Выражение.Найти(ТекстHTML);

Если Результат <> Неопределено Тогда
    Цена = Результат.Группы[1].Значение;
КонецЕсли;

Если встроенный объект регулярных выражений недоступен в вашей версии платформы, в среде Windows можно использовать COMОбъект("VBScript.RegExp").

Вариант 5. Ограничения динамических страниц (SPA) и внешние утилиты

Выясним причину, по которой парсинг может не приносить результата. Если сайт разработан с использованием динамических JavaScript-фреймворков (Single Page Applications) или подгружает каталог через асинхронные AJAX-запросы, то исходный HTML, полученный через HTTPСоединение или ЧтениеHTML, не будет содержать полезных данных.

В этом случае применимы следующие решения:

  1. Анализ сетевых запросов: с помощью инструментов разработчика в браузере найдите прямые API-запросы сайта (обычно возвращающие чистый JSON) и отправляйте запросы сразу к ним, минуя разбор разметки.
  2. Использование ПолеHTMLДокумента: в интерактивном режиме на форме можно загрузить страницу в элемент управления ПолеHTMLДокумента, дождаться завершения скриптов и прочитать свойство Документ (подходит только для клиентских сценариев).
  3. Внешние headless-браузеры: при серверном парсинге используются внешние микросервисы на базе Puppeteer, Playwright или Selenium. Они запускают реальный браузер без интерфейса, выполняют JavaScript и возвращают в 1С уже сгенерированный итоговый HTML.
← На главную