Как распарсить таблицу со страницы сайта в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Разработка механизмов взаимодействия с веб-ресурсами в среде 1С 7.7 сопряжена с рядом трудностей: от поддержки современных протоколов шифрования (HTTPS/TLS) до обработки "грязного" HTML-кода, который не является валидным XML. В данной статье мы подробно разберем, как программно получить данные из таблицы на стороннем сайте, проанализируем типичные ошибки и рассмотрим несколько эффективных способов решения задачи.

Постановка задачи и основные препятствия

Представим ситуацию: нам необходимо отправить запрос на защищенный адрес вида https://сайт/СекретныйКод, получить ответ в формате HTML и извлечь данные из определенной таблицы для загрузки в справочник или документ 1С. Основная проблема заключается в том, что стандартный парсер MSXML2.DOMDocument крайне чувствителен к синтаксису. Если на странице есть незакрытые теги, специфические символы (например, амперсанды в ссылках) или скрипты с логическими операторами, парсер выдаст ошибку: "Имя начинается с ошибочного знака".

Способ 1. Использование объекта HTMLFile (DOM-модель)

Проанализируем наиболее универсальный подход, который не требует строгой валидности документа. Использование объекта HTMLFile (движок Internet Explorer) позволяет работать с HTML-кодом так же, как это делает браузер. Это избавляет нас от необходимости "причесывать" код под стандарты XML.

Рассмотрим по шагам, как реализовать этот метод:

  1. Создаем объект для выполнения HTTP-запроса.
  2. Получаем текст страницы.
  3. Загружаем текст в объект HTMLFile.
  4. Обращаемся к коллекции таблиц и перебираем строки и ячейки.

// Пример получения данных через WinHttp и HTMLFile
Процедура ЗагрузитьТаблицуССайта()
    Попытка
        // Используем WinHttp для работы с HTTPS
        HTTP = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
        HTTP.Open("GET", "https://site.ru/data_page", 0);
        HTTP.Send();
        
        Если HTTP.Status <> 200 Тогда
            Предупреждение("Ошибка доступа к сайту: " + HTTP.Status);
            Возврат;
        КонецЕсли;
        
        ТекстСтраницы = HTTP.ResponseText;
        
        // Создаем объект HTML-документа
        HTML = СоздатьОбъект("htmlfile");
        HTML.write(ТекстСтраницы);
        
        // Ищем все таблицы на странице
        ВсеТаблицы = HTML.getElementsByTagName("table");
        Если ВсеТаблицы.length = 0 Тогда
            Предупреждение("Таблицы на странице не найдены!");
            Возврат;
        КонецЕсли;
        
        // Допустим, нам нужна первая таблица (индекс 0)
        НужнаяТаблица = ВсеТаблицы.item(0);
        
        // Перебор строк таблицы
        Для и = 0 По НужнаяТаблица.rows.length - 1 Цикл
            СтрокаТаблицы = НужнаяТаблица.rows.item(и);
            
            // Перебор ячеек в строке
            Для j = 0 По СтрокаТаблицы.cells.length - 1 Цикл
                ЗначениеЯчейки = СтрокаТаблицы.cells.item(j).innerText;
                Сообщить("Строка " + и + ", Колонка " + j + ": " + ЗначениеЯчейки);
            КонецЦикла;
        КонецЦикла;
        
    Исключение
        Сообщить("Ошибка: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Способ 2. Преобразование HTML в валидный XML через Tidy

Если вы привыкли работать с selectNodes и XPath запросами через MSXML2.DOMDocument, вам придется столкнуться с проблемой невалидности HTML. Как справедливо отмечено в обсуждении, обычный HTML нужно "причесать" до состояния XHTML. Для этого идеально подходит библиотека Tidy.

Рассмотрим алгоритм действий при использовании TidyCOM:

  1. Скачиваем и регистрируем в системе компоненту TidyCOM.
  2. Передаем ей "грязный" HTML.
  3. На выходе получаем чистый XML, который легко читается стандартным парсером 1С.

Посмотрим на пример кода, реализующий эту логику:


// Предположим, файл сохранен локально или получен в переменную
Tidy = СоздатьОбъект("TidyCOM.TidyObject");
// Настраиваем параметры вывода в XML
Tidy.Options.Xhtml = 1; 
Tidy.Options.XmlOut = 1;
Tidy.Options.CharEncoding = "utf8";

// Очищаем код
CleanHTML = Tidy.TidyMemToMem(ТекстСтраницы);

// Теперь можно использовать MSXML
XMLDoc = СоздатьОбъект("MSXML2.DOMDocument.6.0");
XMLDoc.loadXML(CleanHTML);

Если XMLDoc.parseError.errorCode <> 0 Тогда
    Сообщить("Ошибка парсинга: " + XMLDoc.parseError.reason);
Иначе
    // Используем XPath для поиска данных
    Узлы = XMLDoc.selectNodes("//table[@id='myTable']/tr/td");
    // Дальнейшая обработка узлов...
КонецЕсли;

Способ 3. Решение проблемы с кодировками (UTF-8)

Выясним причину, по которой 1С 7.7 часто некорректно отображает русские символы при загрузке данных с сайтов. Большинство современных ресурсов используют кодировку UTF-8, в то время как 1С 7.7 работает с Windows-1251. Если использовать HTTP.ResponseText, объект WinHttp может попытаться автоматически определить кодировку и ошибиться.

Рассмотрим, как правильно перекодировать данные с помощью ADODB.Stream. Это гарантирует сохранение кириллицы в читаемом виде:


// Получаем бинарные данные
BinaryData = HTTP.ResponseBody;

// Используем поток для смены кодировки
Stream = СоздатьОбъект("ADODB.Stream");
Stream.Type = 1; // Binary
Stream.Open();
Stream.Write(BinaryData);
Stream.Position = 0;
Stream.Type = 2; // Text
Stream.Charset = "utf-8"; // Исходная кодировка сайта
РезультатТекст = Stream.ReadText();
Stream.Close();

Способ 4. Использование VBScript как "прокладки"

В некоторых случаях удобно вынести логику обработки текста во внешний скрипт, используя MSScriptControl. Это позволяет использовать возможности регулярных выражений или функций JavaScript/VBScript, которые в 1С 7.7 реализуются сложнее.

Проанализируем ситуацию: если нам нужно вырезать только содержимое между тегами <table> и </table>, мы можем добавить код сценария прямо в 1С:


Script = СоздатьОбъект("MSScriptControl.ScriptControl");
Script.Language = "VBScript";
// Добавляем функцию поиска подстроки
Script.AddCode("
|Function GetTable(txt)
|    Set re = New RegExp
|    re.Pattern = ""<table[^>]*>([\s\S]*?)<\/table>""
|    re.IgnoreCase = True
|    Set matches = re.Execute(txt)
|    If matches.Count > 0 Then
|        GetTable = matches(0).Value
|    Else
|        GetTable = """"
|    End If
|End Function");

ТаблицаHTML = Script.Run("GetTable", ТекстСтраницы);

Рекомендации по выбору метода

Подводя итог, можно выделить следующие рекомендации для разработчика:

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

← На главную