Зачастую перед разработчиком 1С встает задача интеграции с веб-ресурсами, которые не предоставляют готового API (REST или SOAP). В таких случаях единственным способом получения данных становится парсинг — программный разбор HTML-кода страниц сайта. В этой статье мы подробно рассмотрим, как реализовать этот процесс, разберем типичные ошибки новичков и изучим профессиональные инструменты, доступные в платформе 1С:Предприятие.
Начнем с самого простого и наглядного способа, который часто используют начинающие разработчики. Он заключается в размещении на управляемой форме элемента с типом ПолеHTMLДокумента. Этот метод удобен тем, что 1С сама берет на себя загрузку страницы и формирование объектной модели документа (DOM). Рассмотрим базовый пример кода, который срабатывает после загрузки страницы:
&НаКлиенте
Процедура HTMLДокументСформирован(Элемент)
// Получаем доступ к объектной модели документа
Документ = Элементы.HTML.Документ;
// Получаем весь HTML-код страницы
ТхтСтраницы = Документ.documentElement.innerHTML;
// Перебираем дочерние узлы корневого элемента
КолУзлов = Документ.documentElement.childNodes.length - 1;
Для ии = 0 По КолУзлов Цикл
ИмяУзла = Документ.documentElement.childNodes[ии].nodeName;
Сообщить("Найден узел: " + ИмяУзла);
КонецЦикла;
КонецПроцедуры
Хотя этот метод кажется простым, у него есть существенный недостаток: он требует наличия открытой формы и визуальной отрисовки страницы. Это замедляет работу и делает невозможным выполнение задачи в фоновом задании на сервере, где обычно используются алгоритмы и регламентные задания.
Разберем один из самых частых вопросов, возникающих при работе с DOM: в чем разница между коллекциями childNodes и children? Проанализируем техническую суть:
childNodes вы часто будете встречать узлы с именем #text.div, table, a и т.д.). Использование children позволяет избежать «мусора» в виде пустых строк и сосредоточиться на структуре данных.Рекомендация: Для поиска конкретных данных на странице всегда отдавайте предпочтение коллекции children, если вам не нужно анализировать текстовое содержимое вне тегов.
Для создания надежных и быстрых решений мы рекомендуем использовать объекты HTTPСоединение, ЧтениеHTML и ПостроительDOM. Это позволяет загружать и анализировать страницы на стороне сервера. Рассмотрим этот процесс по шагам.
Шаг 1: Получение HTML-кода страницы. Для этого мы создаем соединение с сервером и выполняем GET-запрос (подобным образом работает получение данных о контрагенте с внешних сайтов по API):
Соединение = Новый HTTPСоединение("example.com");
Запрос = Новый HTTPЗапрос("/catalog/products");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ТекстHTML = Ответ.ПолучитьТелоКакСтроку();
Иначе
Возврат; // Обработка ошибки
КонецЕсли;
Шаг 2: Преобразование строки в дерево DOM. Теперь нам нужно превратить сырой текст в структуру, по которой можно перемещаться:
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(ТекстHTML);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеHTML);
После этого объект ДокументDOM становится доступен для анализа так же, как и в поле HTML-документа на форме, но работает это значительно быстрее и стабильнее (в некоторых случаях может потребоваться дополнительная обработка сжатого в Zip http-ответа).
Проанализируем ситуацию, когда нужные данные (например, цена товара) находятся глубоко внутри сложной верстки. Перебирать все узлы циклами крайне неэффективно. Здесь на помощь приходит язык запросов XPath, который поддерживается в 1С 8.3.
Вместо десятка вложенных условий мы можем написать одну строку. Например, чтобы найти все ссылки с определенным классом, используем следующий подход:
// Создаем объект для работы с XPath
Распознаватель = Новый РаспознавательПространствИменDOM(ДокументDOM);
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath("//a[@class='product-link']", ДокументDOM, Распознаватель);
Узел = РезультатXPath.ПолучитьСледующий();
Пока Узел <> Неопределено Цикл
Сообщить("Найдена ссылка: " + Узел.ТекстовоеСодержимое);
Узел = РезультатXPath.ПолучитьСледующий();
КонецЦикла;
Если ваша задача — не просто разобрать одну страницу, а «просмотреть весь сайт», вам потребуется реализовать алгоритм обхода. Выясним, как это сделать наиболее эффективно:
сайт.рф/sitemap.xml). Это XML-файл, в котором перечислены все актуальные страницы. Прочитать его в 1С можно с помощью объекта ЧтениеXML, что гораздо проще, чем искать ссылки на страницах вручную.a на каждой странице, отфильтровывать внешние ссылки (ведущие на другие сайты) и добавлять новые адреса в очередь для обработки. Обязательно ведите список уже посещенных страниц, чтобы программа не вошла в бесконечный цикл.В современных версиях платформы (начиная с 8.3.14) 1С сменила движок отображения HTML с устаревшего Internet Explorer на современный Chromium. Это критически важно, так как многие современные сайты используют скрипты, которые просто не работают в старых браузерах. Если вы используете поле формы, убедитесь, что в свойствах конфигурации или конкретного элемента включен современный режим отображения.
Также стоит помнить о защите сайтов от роботов. Чтобы ваш парсер не заблокировали, придерживайтесь следующих правил:
— Устанавливайте заголовки User-Agent в объекте HTTPЗапрос, чтобы имитировать работу реального браузера.
— Используйте задержки между запросами с помощью команды Приостановить(2) (на 2 секунды), чтобы не создавать чрезмерную нагрузку на сервер-источник.
В редких случаях, когда HTML-код сайта «битый» или содержит ошибки, стандартный ПостроительDOM может выдать ошибку при чтении. В такой ситуации мы можем прибегнуть к регулярным выражениям (RegExp). В 1С это реализуется через COM-объект VBScript.RegExp. Рассмотрим пример поиска артикула по шаблону:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
// Шаблон для поиска текста вида "Артикул: 12345"
RegExp.Pattern = "Артикул:\s*(\d+)";
Matches = RegExp.Execute(ТекстHTML);
Для Каждого Match Из Matches Цикл
Сообщить("Найден артикул: " + Match.SubMatches(0));
КонецЦикла;
Подводя итог, можно сказать, что 1С предоставляет мощный инструментарий для парсинга. Несмотря на то, что 1С — это в первую очередь учетная система, использование связки HTTPСоединение + ПостроительDOM + XPath превращает её в полноценный инструмент для сбора и анализа данных из интернета.