Разработка механизмов взаимодействия с веб-ресурсами в среде 1С 7.7 сопряжена с рядом трудностей: от поддержки современных протоколов шифрования (HTTPS/TLS) до обработки "грязного" HTML-кода, который не является валидным XML. В данной статье мы подробно разберем, как программно получить данные из таблицы на стороннем сайте, проанализируем типичные ошибки и рассмотрим несколько эффективных способов решения задачи.
Представим ситуацию: нам необходимо отправить запрос на защищенный адрес вида https://сайт/СекретныйКод, получить ответ в формате HTML и извлечь данные из определенной таблицы для загрузки в справочник или документ 1С. Основная проблема заключается в том, что стандартный парсер MSXML2.DOMDocument крайне чувствителен к синтаксису. Если на странице есть незакрытые теги, специфические символы (например, амперсанды в ссылках) или скрипты с логическими операторами, парсер выдаст ошибку: "Имя начинается с ошибочного знака".
Проанализируем наиболее универсальный подход, который не требует строгой валидности документа. Использование объекта HTMLFile (движок Internet Explorer) позволяет работать с HTML-кодом так же, как это делает браузер. Это избавляет нас от необходимости "причесывать" код под стандарты XML.
Рассмотрим по шагам, как реализовать этот метод:
HTMLFile.
// Пример получения данных через 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 + ": " + ЗначениеЯчейки);
КонецЦикла;
КонецЦикла;
Исключение
Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если вы привыкли работать с selectNodes и XPath запросами через MSXML2.DOMDocument, вам придется столкнуться с проблемой невалидности HTML. Как справедливо отмечено в обсуждении, обычный HTML нужно "причесать" до состояния XHTML. Для этого идеально подходит библиотека Tidy.
Рассмотрим алгоритм действий при использовании TidyCOM:
Посмотрим на пример кода, реализующий эту логику:
// Предположим, файл сохранен локально или получен в переменную
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");
// Дальнейшая обработка узлов...
КонецЕсли;
Выясним причину, по которой 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();
В некоторых случаях удобно вынести логику обработки текста во внешний скрипт, используя 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", ТекстСтраницы);
Подводя итог, можно выделить следующие рекомендации для разработчика:
User-Agent в объекте WinHttp, имитируя работу реального браузера.Применяя эти подходы, вы сможете эффективно автоматизировать сбор данных с любых веб-ресурсов в среде 1С 7.7, обеспечивая надежность и корректность обработки информации.