При автоматизации взаимодействия 1С с внешними веб-ресурсами программисты часто прибегают к использованию COM-объекта InternetExplorer.Application. Это позволяет программно открывать страницы, заполнять формы и считывать результаты. Однако структура современных сайтов бывает сложной, и добраться до конкретного текстового значения внутри вложенных таблиц и контейнеров div бывает непросто. В этой статье мы разберем, как эффективно находить нужные элементы и как избежать распространенной ошибки, когда элемент «не найден» из-за слишком быстрой работы кода.
Для начала проанализируем процесс создания объекта и загрузки страницы. Чтобы начать работу с HTML-контентом, нам необходимо создать экземпляр браузера и дождаться загрузки целевого URL. Рассмотрим стандартный код инициализации:
IE_COMОбъект = Новый COMОбъект("InternetExplorer.Application");
IE_COMОбъект.Visible = Ложь; // Скрываем окно браузера
IE_COMОбъект.Navigate("https://example.com/page");
После вызова метода Navigate управление возвращается в 1С практически мгновенно. Однако сама страница в браузере еще не загружена. Если мы сразу попытаемся выполнить IE_COMОбъект.Document, мы можем получить ошибку или пустой объект. Поэтому первым шагом всегда является проверка готовности документа.
Выясним причину, по которой код может работать в режиме отладки, но выдавать ошибку «Неопределено» при обычном запуске. В режиме отладки программист делает паузу, просматривая переменные, и за это время браузер успевает загрузить страницу. При обычном выполнении 1С пытается найти элемент в еще не существующем DOM-дереве.
Для решения этой проблемы проанализируем ситуацию и внедрим цикл ожидания. Мы будем проверять состояние ReadyState. Значение 4 означает, что документ полностью загружен.
Пока IE_COMОбъект.ReadyState < 4 Цикл
// Приостанавливаем выполнение, чтобы дать браузеру время
// В управляемых формах используем обработчик ожидания,
// в обычных или внешних обработках можно использовать небольшую паузу
Предупреждение("Ожидание загрузки...", 1);
КонецЦикла;
IE_doc = IE_COMОбъект.Document;
Важный нюанс: даже если ReadyState равен 4, данные могут подгружаться скриптами (AJAX) внутри страницы. В таких случаях рекомендуется искать конкретный элемент в цикле в течение нескольких секунд, пока он не появится в дереве.
Допустим, у нас есть сложная структура вложенности, как в примере автора:
<div id="cpasContent"> ... <td class="cpasrez"> Текст </td> ... </div>
Рассмотрим подробнее методы поиска. Использование последовательного перебора всех дочерних узлов (ChildNodes) крайне неудобно и ненадежно, так как любое изменение верстки сайта сломает ваш код. Вместо этого разберем по шагам использование современных CSS-селекторов через метод querySelector.
rez = IE_doc.getElementByID("cpasContent");.querySelector используется точка перед именем класса.
// Находим элемент с классом cpasrez внутри блока cpasContent
ЦелевойЭлемент = rez.querySelector(".cpasrez");
Если ЦелевойЭлемент <> Неопределено Тогда
РезультатТекст = ЦелевойЭлемент.innerText;
Сообщить("Найден текст: " + РезультатТекст);
КонецЕсли;
Метод querySelector возвращает первый найденный элемент, соответствующий критерию. Если вам нужно получить список всех подобных элементов (например, все строки таблицы), используйте querySelectorAll, который вернет коллекцию объектов.
При получении данных из найденного узла мы можем использовать разные свойства. Посмотрим на их отличия:
innerText, но может содержать «лишние» пробелы и отступы из исходного кода страницы.Если метод querySelector недоступен (например, в старых версиях библиотек системы), проанализируем альтернативные варианты:
Элементы = rez.getElementsByClassName("cpasrez");
Если Элементы.length > 0 Тогда
НужныйТекст = Элементы.item(0).innerText;
КонецЕсли;
td и перебрать их в цикле, проверяя содержимое соседних ячеек.Проанализируем критически важный аспект работы с COM-объектами. Internet Explorer — это отдельное приложение. Если вы просто очистите переменную в 1С (IE_COMОбъект = Неопределено;), процесс iexplore.exe может остаться висеть в памяти компьютера, потребляя ресурсы. При многократном запуске обработки это может привести к зависанию сервера или клиентской машины.
Всегда закрывайте приложение явно:
// После завершения всех манипуляций
IE_COMОбъект.Quit();
IE_COMОбъект = Неопределено;
Разберем ситуацию, когда использование тяжелого Internet Explorer не оправдано. Если сайт не требует выполнения сложного JavaScript для отображения данных, гораздо быстрее и стабильнее использовать связку HTTPСоединение и ПостроительDOM.
Соединение = Новый HTTPСоединение("example.com");
Запрос = Новый HTTPЗапрос("/page");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
ПостроительDOM = Новый ПостроительDOM;
ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);
// Теперь можно работать с ДокументHTML методами 1С
КонецЕсли;
Этот метод работает в фоновых заданиях на сервере гораздо надежнее, чем COM-объект, так как не зависит от графической оболочки Windows и настроек безопасности браузера.
Подведем итог: для успешного извлечения данных через InternetExplorer.Application необходимо обеспечить полную загрузку страницы через проверку ReadyState, использовать селекторы querySelector для точного позиционирования и не забывать про вызов метода Quit() для корректного завершения сессии браузера.