При разработке механизмов парсинга сайтов в среде 1С программисты часто сталкиваются с ситуацией, когда вместо ожидаемого HTML-кода страницы сервер возвращает заголовок "301 Moved Permanently". Это означает, что запрашиваемый ресурс был окончательно перемещен на новый адрес. Чаще всего это происходит при переходе сайта с протокола http на защищенный протокол https. Разберем пошагово, как правильно настроить соединение, обработать перенаправления и извлечь данные из объектной модели документа (DOM).
Первым делом проанализируем ситуацию: код 301 сообщает нам, что мы обращаемся по старому адресу. В современных реалиях это почти всегда означает необходимость использования SSL-соединения. Если в коде создания HTTPСоединение не указан параметр защищенного соединения, 1С пытается выполнить обычный HTTP-запрос, в то время как сервер требует HTTPS.
Рассмотрим, как правильно инициализировать объект HTTPСоединение. Важно помнить, что 1С требует явного указания объекта ЗащищенноеСоединениеOpenSSL, если вы работаете с протоколом HTTPS. Просто передать Истина в некоторых случаях недостаточно, лучше использовать стандартный конструктор.
Посмотрим на пример правильной инициализации соединения:
// Определяем параметры сервера
Сервер = "www.brass.ru"; // Имя сервера без протокола
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем соединение с указанием защищенного протокола
Соединение = Новый HTTPСоединение(Сервер, , , , , , Защита);
Обратите внимание на структуру параметров: имя сервера передается без префиксов http:// или https://. Это распространенная ошибка, которая приводит к невозможности установить связь.
Если после настройки SSL сайт все равно возвращает 301 или 302 код, значит, страница была перемещена на другой URL (например, сменилась структура каталога). В отличие от браузеров, объект HTTPСоединение в 1С не всегда автоматически следует по цепочке перенаправлений. Нам необходимо самостоятельно получить новый адрес из заголовка Location.
Проанализируем алгоритм обработки заголовков. Поскольку Заголовки в объекте HTTPОтвет являются Соответствием, обращение к ним идет через квадратные скобки. Выясним, куда нас перенаправляет сервер:
Запрос = Новый HTTPЗапрос("/old-path/page.html");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 301 Или Ответ.КодСостояния = 302 Тогда
// Получаем новый адрес из заголовка Location
НовыйАдрес = Ответ.Заголовки["Location"];
Сообщить("Страница перенесена. Новый адрес: " + НовыйАдрес);
// Здесь следует организовать повторный запрос по новому адресу
КонецЕсли;
Рекомендуется реализовывать это в цикле (не более 5-7 итераций), чтобы корректно проходить через цепочки редиректов. Также важно проверять, является ли путь в Location абсолютным (содержит домен) или относительным (начинается с /). Если путь относительный, его нужно «склеить» с базовым адресом сервера.
Разберем типичную ошибку при формировании запроса. Многие начинающие разработчики пытаются передать полный URL в конструктор соединения или запроса. Проанализируем правильный подход: объект HTTPСоединение отвечает за связь с хостом (сервером), а HTTPЗапрос — за получение конкретной страницы или ресурса на этом хосте.
Рассмотрим пример:
https://forum.infostart.ru/forum9/topic228200/Сервер должна содержать: forum.infostart.ruПутьКСтранице (ресурс) должна содержать: /forum9/topic228200/Именно в таком виде данные должны передаваться в объекты 1С, иначе вы получите ошибку 404 или ошибку параметров запроса.
Бывают ситуации, когда соединение установлено, код ответа 200 (ОК), но полученный файл имеет подозрительно маленький размер (например, 6 Кб) и содержит страницу с ошибкой 404 или сообщением о блокировке. Выясним причину: современные сайты защищаются от простых ботов. Если 1С не представляется браузером, сервер может отдать пустую страницу или ошибку.
Для решения этой проблемы мы должны добавить заголовок User-Agent в наш запрос. Рассмотрим, как это сделать:
Запрос = Новый HTTPЗапрос(ПутьКСтранице);
// Имитируем работу браузера Chrome
Запрос.Заголовки.Вставить("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");
Запрос.Заголовки.Вставить("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
Ответ = Соединение.Получить(Запрос);
Это значительно повышает шансы на успешное получение реального содержимого страницы.
После того как мы успешно получили тело страницы в виде строки или сохранили его в файл, наступает этап извлечения данных. В 1С для этого используется ЧтениеHTML и ПостроительDOM. Однако здесь есть свои нюансы. Проанализируем ситуацию, когда метод ПолучитьЭлементыПоИмени("ul") возвращает пустую таблицу.
Возможные причины:
"UL" вместо "ul".ПостроительDOM может некорректно построить дерево. В этом случае чтение документа может прерваться раньше времени.ul с данными просто не будет.Рассмотрим пример правильного обхода элементов:
ЧтениеХТМЛ = Новый ЧтениеHTML;
ЧтениеХТМЛ.УстановитьСтроку(СтрокаСHTMLДанными); // Либо чтение из файла
ПостроительДОМ = Новый ПостроительDOM;
ДокументХТМЛ = ПостроительДОМ.Прочитать(ЧтениеХТМЛ);
// Ищем все элементы списка
СписокЭлементов = ДокументХТМЛ.ПолучитьЭлементыПоИмени("ul");
Для Каждого Элемент Из СписокЭлементов Цикл
// Проанализируем содержимое каждого списка
Сообщить("Найден список: " + Элемент.ИмяУзла);
// Дальнейшая обработка вложенных тегов li
КонецЦикла;
Если штатные средства HTTPСоединение и ПостроительDOM не справляются с особенностями конкретного сайта (например, сложная кодировка или специфические требования к TLS), можно рассмотреть использование внешних компонентов. Одним из надежных вариантов является использование объекта WinHttp.WinHttpRequest.5.1 через механизм COMОбъект. Этот метод позволяет более гибко управлять таймаутами, прокси-серверами и автоматическими редиректами.
Подводя итог, можно сказать, что успешный парсинг в 1С складывается из трех составляющих: правильная настройка SSL, корректная передача HTTP-заголовков (особенно User-Agent) и внимательный разбор полученного DOM-дерева с учетом особенностей верстки сайта.