Разработка интеграций с веб-ресурсами — одна из наиболее частых задач в экосистеме 1С. Нам регулярно требуется загружать актуальные курсы валют, обновлять каталоги товаров, получать цены конкурентов или информацию о заказах из маркетплейсов. Однако при первой же попытке получить веб-страницу начинающие разработчики сталкиваются с рядом неочевидных проблем: от сетевых ошибок подключения до сложностей с разбором полученного кода.
В этой статье мы подробно разберем, почему возникает популярная ошибка «Couldn't resolve host name», как правильно настроить безопасное HTTPS-соединение, как получить веб-страницу сразу в виде текстовой строки без создания лишних временных файлов и как извлечь нужные данные (например, цену товара) без использования медленных и хрупких строковых функций.
Часто при выполнении кода запроса к сайту разработчики сталкиваются с исключением:
Ошибка работы с Интернет: Couldn't resolve host name
Давайте выясним причину возникновения этой ошибки. Она означает, что DNS-сервер не смог преобразовать указанное текстовое имя сайта в IP-адрес. В большинстве случаев проблема кроется в неверном разделении адреса страницы на имя сервера (хост) и путь к ресурсу (строку запроса) при создании объектов 1С.
Проанализируем типичный ошибочный пример:
АдресСервера = "market.yandex.ru/"; // Ошибка! Слэш на конце недопустим
ПутьКСтранице = "product--diktofon-ritmix-rr-120-4gb/106652249";
Соединение = Новый HTTPСоединение(АдресСервера);
Конструктор объекта HTTPСоединение ожидает в качестве первого параметра чистое доменное имя (например, market.yandex.ru) или IP-адрес. Наличие символа слэша / в конце строки хоста заставляет систему воспринимать его как часть имени сервера. Символ слэша не может входить в состав доменного имени, поэтому DNS-клиент выдает ошибку сопоставления имени.
Рассмотрим правильный вариант разделения адреса:
// Чистый домен без протокола (http/https) и без закрывающего слэша
АдресСервера = "market.yandex.ru";
// Путь к конкретной странице, начинающийся с ведущего слэша
ПутьКСтранице = "/product--diktofon-ritmix-rr-120-4gb/106652249";
Современные веб-сайты практически повсеместно работают по защищенному протоколу HTTPS. Если вы попытаетесь обратиться к ресурсу, требующему SSL, через обычное HTTP-соединение, сервер либо вернет ошибку, либо перенаправит вас (код состояния 301/302), что потребует дополнительной обработки.
Для работы с HTTPS в платформе 1С необходимо использовать объект ЗащищенноеСоединениеOpenSSL. Давайте посмотрим на универсальный пример инициализации безопасного соединения:
// Инициализируем защищенное соединение с использованием системных сертификатов безопасности
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем HTTP-соединение с указанием защищенного соединения в параметрах
СоединениеHTTP = Новый HTTPСоединение(
"market.yandex.ru", // Сервер
,,,, // Порт, Пользователь, Пароль, Прокси (пропускаем дефолтные параметры)
ЗащищенноеСоединение // Защищенное соединение
);
Если на сервере, где выполняется код 1С, отсутствует прямой выход в интернет, не забудьте настроить параметры прокси-сервера и передать их в соответствующий параметр конструктора HTTPСоединение.
В старых версиях платформы 1С для получения данных приходилось сначала скачивать файл на диск во временную директорию с помощью метода Получить(), а затем читать его содержимое через объект ТекстовыйДокумент или ЧтениеТекста. Это приводило к лишним дисковым операциям ввода-вывода и замедляло работу системы.
Начиная с современных версий платформы 8.3, мы можем использовать более элегантный объектный метод — получение тела ответа непосредственно в оперативную память в виде строки. Для этого используются объекты HTTPЗапрос и HTTPОтвет.
Разберем готовый шаблон функции для получения HTML-кода страницы в виде строки:
Функция ПолучитьHTMLКодСтраницы(Сервер, ПутьКСтранице) Экспорт
РезультатТекст = "";
// Инициализируем SSL-соединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
СоединениеHTTP = Новый HTTPСоединение(Сервер, , , , , , ЗащищенноеСоединение);
// Создаем запрос к конкретному адресу страницы
HTTPЗапрос = Новый HTTPЗапрос(ПутьКСтранице);
Попытка
// Выполняем GET-запрос к серверу
Ответ = СоединениеHTTP.Получить(HTTPЗапрос);
// Проверяем успешность выполнения запроса (код состояния 200 OK)
Если Ответ.КодСостояния = 200 Тогда
// Получаем HTML-код напрямую в строку без записи на диск
РезультатТекст = Ответ.ПолучитьТелоКакСтроку("UTF-8");
Иначе
Сообщить(СтрШаблон("Сервер вернул ошибку. Код состояния: %1", Ответ.КодСостояния));
КонецЕсли;
Исключение
Сообщить("Произошла ошибка при выполнении HTTP-запроса: " + ОписаниеОшибки());
КонецПопытки;
Возврат РезультатТекст;
КонецФункции
Предположим, мы успешно получили HTML-код страницы. Теперь перед нами стоит задача извлечь из него конкретное значение, например, цену товара, которая в коде представлена следующим образом:
<div class="n-product-price-cpa2__price"><span class="price">1 590 ₽</span></div>
Использование функций работы со строками Найти, Сред, Лев или Прав крайне не рекомендуется. Во-первых, это требует написания сложных громоздких циклов с высчитыванием индексов символов. Во-вторых, малейшее изменение верстки сайта (например, добавление лишнего пробела или нового атрибута в тег) мгновенно сломает ваш алгоритм.
Рассмотрим два надежных и современных способа парсинга данных в 1С.
Платформа 1С предоставляет мощные встроенные инструменты для объектного разбора XML- и HTML-документов. Мы можем загрузить полученный HTML-текст в объектную модель DOM и работать с тегами как с коллекцией объектов.
Рассмотрим пример поиска цены по имени тега и его классу:
// Загружаем HTML-строку в парсер
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(ТекстHTML);
ПостроительDOM = Новый ПостроительDOM;
ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);
// Ищем все элементы с тегом "span" на странице
СписокЭлементов = ДокументHTML.ПолучитьЭлементыПоИмени("span");
Для Каждого Элемент Из СписокЭлементов Цикл
// Проверяем наличие класса "price" у найденного тега
Класс = Элемент.ПолучитьАтрибут("class");
Если Класс = "price" Тогда
ЦенаСтрокой = Элемент.ТекстовоеСодержимое; // Получаем текст внутри тега
Сообщить("Найдена цена товара: " + СократитьЛП(ЦенаСтрокой));
Прервать; // Выходим из цикла после успешного нахождения цены
КонецЕсли;
КонецЦикла;
Этот способ максимально надежен, так как парсер DOM корректно обрабатывает структуру документа, игнорируя незначительные изменения в позиционировании тегов.
Если вам требуется быстро извлечь данные по шаблону, а структура документа достаточно проста, можно прибегнуть к регулярным выражениям. Начиная с версии платформы 8.3.24, регулярные выражения поддерживаются в 1С нативно.
Рассмотрим пример использования регулярных выражений для поиска цены:
ШаблонРегулярки = "<span[^>]*class=""price""[^>]*>([^<]+)</span>";
РезультатыПоиска = СтрНайтиПоРегулярномуВыражению(ТекстHTML, ШаблонРегулярки);
Если РезультатыПоиска.НачальнаяПозиция <> 0 Тогда
// Извлекаем найденную подстроку из текста HTML
НайденныйТекст = Сред(ТекстHTML, РезультатыПоиска.НачальнаяПозиция, РезультатыПоиска.Длина);
Сообщить("Найден тег цены: " + НайденныйТекст);
КонецЕсли;
Для более старых версий платформы можно использовать COM-объект VBScript.RegExp, который доступен на операционных системах семейства Windows.
Иногда разработчики сталкиваются с тем, что в инспекторе кода браузера они видят детальную структуру страницы со всеми скидками и ценами, а при получении этой же страницы через 1С возвращается урезанный HTML-код без нужных данных. Давайте разберем три главные причины этого явления.
HTTPСоединение в 1С — это простой клиент, который только скачивает стартовый HTML-файл, но не умеет выполнять JavaScript. Соответственно, все элементы, генерируемые скриптами "на лету", в полученную строку просто не попадают.User-Agent: 1C+Enterprise/8.3). Крупные ресурсы и маркетплейсы моментально идентифицируют такие запросы как парсеры-роботы и отдают им пустую страницу, страницу авторизации или капчу. Чтобы обойти это ограничение, необходимо маскировать запросы под реальный браузер пользователя:
ЗаголовкиЗапроса = Новый Соответствие;
ЗаголовкиЗапроса.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36");
HTTPЗапрос = Новый HTTPЗапрос(ПутьКСтранице, ЗаголовкиЗапроса);
Если прямой парсинг HTML-страниц регулярно дает сбои из-за частой смены верстки или блокировок со стороны сайтов, стоит рассмотреть более надежные подходы к интеграции:
ПрочитатьJSON(), чем парсить сложную верстку HTML.Применяя данные подходы, вы сможете создавать стабильные, быстрые и надежные механизмы обмена данными между вашей информационной базой 1С и любыми веб-ресурсами.