Получить html код страницы 1с

Обновлено: 07.07.2024

Итак нам надо загрузить html-страницы с сайта. В качестве исходных данных имеем текстовый файл с ссылками на страницы, необходимо загрузить эти страницы в элементы справочника 1с конфигурации. Во время загрузки надо предусмотреть сохранение картинок в конфигурации 1с, а не опираться на их доступность на сайте-источнике.

Пользователю в форме списка справочника доступна кнопка загрузки страниц. По данной кнопке происходит передача текстового файла с ссылками на сервер и отдается управление в общий модуль ОбменССайтомСервер. Каждая строка текстового файла воспринимается как ссылка. Чтение текстового файла можно посмотреть в функции ЗагрузитьОбъектыИзСсылокФайла().

Хочу остановиться подробнее на самом алгоритме загрузки html-страницы. Саму загрузку по ссылке производит функция ЗагрузитьССайта, которая возвращает форматированный документ. Для того чтобы сформировать форматированный документ используется метод УстановитьHTML. Для вызова этого метода нам необходимо наличие текстовой строки, которая содержит HTML и структуру вложений. В структуре вложений ключ структуры это название картинки, а в значении хранится сама картинка.

Код получения форматированного документа:

Конфигурацию, демонстрирующую решение данной задачи можно скачать

html_to_1C.cf (17,0 KiB, 6 233 скачиваний)

Если будут предложения по оптимизации кода обхода html-кода пишите в комментарии.

UPD: Добавлено приведение строки в нижний регистр. При загрузке страницы используется кеш картинок, параметр КешКартинок имеет тип соответствие и дополняется во время разбора ссылки в случае необходимости. Спасибо Александру за дельные советы в комментариях.

1. Забыли учесть то, что теги могут быть написаны как в нижнем регистре, так и в ВЕРХНЕМ (проверки для поиска тэга img и атрибута src).

Александр, спасибо большое за указание на неточности. По первому пункту надо добавить использование ВРег() в условиях.
Кеширование картинок во время скачивания сделать в соответствии так же реально, так как сервер файл отрабатывает за один вызов и не надо будет думать про сохранение переменной на сервере между вызовами клиента.
Спасибо.

Обновил пост. Спасибо.

На своих данных с такой ситуацией не сталкивался. Интересный момент. Спасибо за дополнение

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

Теперь необходимо разобраться, как получать информацию о самих участниках. Опять же глянем исходный код страницы:

В таблице каждая строка представлена 4 ячейками:

  1. Ячейка с классом regional_tour_fio. В данной ячейке размещается фамилия, имя и отчество участника
  2. Ячейка с классом regional_tour__nomination_td. В данной ячейке размещается элемент span, класс которого зависит от номинации, в которой участ вовал пользователь. Таких номинаций три:
    • Бухгалтерский учет и налогообложение (класс nomination b)
    • Кадровый учет и трудовое право (класс nomination k)
    • Платформа 1С:Предприятие 8 – разработка и администрирование (класс nomination it)
  3. Ячейка с классом text-center. В данной ячейке размещается количество баллов, набранных за отборочный тур. Также здесь можно увидеть атрибут title, в котором хранится калькуляция баллов. Например "Тест: 84, акция Вконтакте: 15, акция от партнера: 15". Здесь хотелось бы отметить, что обязательно указывается только "Тест", остальные значения могут не указываться, если участник не принимал участия в акциях партнера или проводимых Вконтакте.
  4. Ячейка без опозновательных знаков :) В ней находится номер сертификата Профессионал 1С:ИТС. Ее будем определять как ячейку без атрибута class.

Создание справочников

Создадим пустую конфигурацию и добавим справочники Участники и Партнеры. На рисунке ниже показаны реквизиты справочников

Реквизиты справочников

В справочнике Участники реквизиты Фамилия, Имя, Отчество, Сертификат имеют тип Строка, БаллыЗаТест, БаллыВК, БаллыПартнер, ОбщиеБаллы имеют тип число и реквизит Партнер имеет тип СправочникСсылка.Партнеры. В справочнике Партнеры все реквизиты имеют тип строка.

Теперь создадим общую форму, с помощью которой будем обновлять информацию в справочниках. В данной форме создадим две команды: ОбновитьИнформацию и ЗакрытьФорму.

Разбор адреса

Начнем писать код в модуле этой формы. Для удобства работы напишем сперва функцию СтруктураАдреса, которая будет разбирать наш адрес по частям и возвращать структуру. Согласно RFC1738, адрес страницы строится следующим образом:

Получение DOM-объектов с веб-страницы

Получение и обработка данных из DOM-объектов

Чтобы получить необходимую информацию, нам необходимо загрузить страницу, где она расположена. Но у нас таких страниц несколько, и для этого нам необходимо обработать элементы списка партнеров. Чтобы получить список партнеров и адреса страниц, нам надо просмотреть все элементы option и получить значение атрибута value, из которого получим адреса страниц и сам текст этого элемента. Поиск элемента в объектах DOM будем осуществлять с помощью метода построителя DOM - ПолучитьЭлементыПоИмени(). В результате работы этого метода мы получим переменную с типом СписокЭлементовDOM(), в котором будут содержаться все элементы option и его содержимое. Для получения атрибута используем метод ПолучитьАтрибут(), а для получения содержимого элемента используем метод ТекстовоеСодержимое() Получить. Эти данные мы сохраним в структуре Партнер("Город", "НомерНаСайте", "Партнер"), которую в свою очередь добавим в массив. Вот тут у меня вопрос к читателям: как лучше сделать - передавать по одной структуре на сервер и там сохранять в справочнике или собрать все структуры в массив и передать массив на сервер? Я попробовал оба варианта, и по мне лучше второй. Далее мы подгружаем все страницы с информацией о участниках поочередно. Для получения информации об участниках необходимо найти таблицу без шапки (элемент tbody) и в нем получить все строки (элемент tr). После этого просматриваем все ячейки строки (элемент td) на соответствие атрибута class одному из условий. Все условия мы с вами рассмотрели ранее. Когда получаем элементы ячеек, нам необходимо выполнить некоторую обработку:

  1. В ячейке "Номинация" необходимо найти элемент span и на основании атрибута class данного элемента получить номинацию;
  2. Разобрать атрибут title в ячейке с количеством баллов, чтобы получить отдельно баллы за тест, за акцию ВК и баллы от партнеров.

Все полученные данные сохраняем в структуру Участник("ФИО", "Номинация", "БаллыТест", "БаллыВК", "БаллыПарт", "ОбщиеБаллы", "Сертификат", "Партнер"). Как и в случае с партнерами, данную структуру добавляем в массив. Полученные массивы отправляем на сервер для сохранения. В итоге функция получилась следующая:

Сохранение данных в справочниках

Для сохранения данных в справочниках мы создадим функции ОбновитьУчастников(МассивУчастников) и ОбновитьПартнеров(МассивПартнеров):

Осталось только сделать приятные мелочи по оформлению, но каждый делает на свой вкус и цвет. Я вывел форму списка справочника Участники единственной на рабочую облать начальной страницы, и вместо вывода номера сертификата я применил условное форматирование (строка выделяется цветом, если человек получил сертификат). В итоге получилось следующее:

Работа с веб-страницами средствами 1С

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

Т.е. вот этой страницы:

Изображение

Для начала создадим внешнюю обработку, добавим реквизит «Адрес « с типом «Строка», неограниченной длины.

Изображение

Форма примет вид:

Изображение

Запустим обработку в режиме «Предприятие» и введем адрес произвольного интернет ресурса. И получим результат:

Изображение

Добавим реквизит формы: «КлючевоеСлово», перенесем на форму.

Если немного покопаться, то можно узнать, что для кодирования переменных в URL’ах можно использовать java-script функцию «encodeURIComponent». Можно, конечно, перебором подобрать код для каждого символа алфавита и самому написать кодировщик, а можно использовать возможности компоненты wscript, которую можно подключить из 1С.

Итак, что нам нужно:

А) Подключить wscript

Б) На основании ключевого слова собрать скрипт, который будет получать значение, возвращенное функцией «encodeURIComponent» при передаче в неё в качестве параметра нашего слова, а затем полученный результат будет записывать в текстовый файл с определенным заранее каталогом

В) Из 1С получать текстовый файл, созданный при помощи wscript и читать его.


// Подключение к сайту 1cnik.by.
// Параметры: адрес, порт (http:80, https:443), пользователь, пароль, прокси, таймаут в секундах, защищ.соединение (для https)
СоединениеHTTP = Новый HTTPСоединение ( "1cnik.by" , 80 , , , , , );

Сообщить ( "Текст страницы: " + РезультатЗапроса . ПолучитьТелоКакСтроку ());

СоединениеHTTP = Новый HTTPСоединение ( "www.yandex.by" , 80 ); // Поиск по Yandex.by

Если РезультатЗапроса . КодСостояния = 302 Тогда // Произошло перенаправление на другую страницу

// Функция СтруктураURI возвращает имя, порт и путь к ресурсу.
СтрURI = СтруктураURI ( РезультатЗапроса . Заголовки . Получить ( "Location" ));

// Сохранение страницы с результатами поиска в виде html файла и тут же покажем его пользователю.
СоздатьКаталог ( КаталогДокументов () + "\1cnik.by" );
ФайлHTML = КаталогДокументов () + "\1cnik.by\index.html" ;

HTMLТекст = Новый ЗаписьТекста ( ФайлHTML , КодировкаТекста . UTF8 );
HTMLТекст . Записать ( Результат . ПолучитьТелоКакСтроку ());
HTMLТекст . Закрыть ();

// Вывод пользователю на экран
ЗапуститьПриложение ( ФайлHTML );
КонецЕсли;

&НаКлиенте
Процедура СохранениеКартинкиССайта ()

// Запись файла easter_960_720.jpg на диск
СоздатьКаталог ( КаталогДокументов () + "\1cnik.by" );
ФайлКартинки = КаталогДокументов () + "\1cnik.by\easter_960_720.jpg" ;
РезультатЗапроса . ПолучитьТелоКакДвоичныеДанные (). Записать ( ФайлКартинки );

// Показываем картинку пользователю
ЗапуститьПриложение ( ФайлКартинки );

ЗаголовкиЗапроса = Новый Соответствие ;
ЗаголовкиЗапроса . Вставить ( "Data" , "format=woff2" );
ЗаголовкиЗапроса . Вставить ( "Base" , "1C" );
ЗаголовкиЗапроса . Вставить ( "Cookie" , "session=701" );

// Подключаемся к сайту.
СоединениеHTTP = Новый HTTPСоединение ( "1cnik.by" );

Proxy = Новый ИнтернетПрокси ;

// Авторизация на сервере
Proxy . Пользователь = "Admin1C" ;
Proxy . Пароль = "8317" ;

// Прокси сервер прописывается для каждого протокола отдельно
Proxy . Установить ( "http" , "192.168.100.2" , "8080" );
Proxy . Установить ( "https" , "192.168.100.2" , "3370" );

СоединениеHTTP = Новый HTTPСоединение ( "1cnik.by" . Proxy );

// Подключение к сайту https://google.by
// Параметры: адрес, порт (http:80, https:443), пользователь, пароль, прокси, таймаут в секундах, защищ.соединение (для https)
СоединениеHTTP = Новый HTTPСоединение ( "google.by" , 443 , , , , , Новый ЗащищенноеСоединениеOpenSSL ());

// Получение текста страницы
ЗапросHTTP = Новый HTTPЗапрос ( "/" ); // Можно указать любую страницу например, "/services" или "/contacts"

// В Cookies нам должны вернуть идентификатор сессии.
Cookie = РезультатЗапроса1 . Заголовки . Получить ( "Set-Cookie" );
Cookie = СтрЗаменить ( Cookie , ";" , Символы . ПС );
ИдентификаторСессии1 = СтрПолучитьСтроку ( Cookie , 1 );

// В cookie нам вернули второй идентификатор.
Cookie = РезультатЗапроса2 . Заголовки . Получить ( "Set-Cookie" );
Cookie = СтрЗаменить ( Cookie , ";" , Символы . ПС );
ИдентификаторСессии2 = СтрПолучитьСтроку ( Cookie , 1 );

// В результате второго Get-запроса возращена страница авторизации
// Получаем из формы авторизации значения параметров name="lt", name="execution" и name="_eventId",
// Чтобы сформировать код приглашения на сайт.
ltValue = "" ; executionValue = "" ; _eventIdValue = "" ;

Строки = Новый ТекстовыйДокумент ;
Строки . УстановитьТекст ( РезультатЗапроса2 . ПолучитьТелоКакСтроку ());
Для Индекс = 0 По Строки . КоличествоСтрок () Цикл
Строка = Строки . ПолучитьСТроку ( Индекс );
Если Найти ( Строка , "name=""lt""" ) > 0 Тогда
ltValue = ВытащитьЗначениеИзСтроки ( Строка );
ИначеЕсли Найти ( Строка , "name=""execution""" ) > 0 Тогда
executionValue = ВытащитьЗначениеИзСтроки ( Строка );
ИначеЕсли Найти ( Строка , "name=""_eventId""" ) > 0 Тогда
_eventIdValue = ВытащитьЗначениеИзСтроки ( Строка );
КонецЕсли;
КонецЦикла;

// Для формирования кода приглашения нужен логин и пароль от сайта 1С:ИТС.
Логин1СИТС = "" ;
Пароль1СИТС = "" ;

Если Логин1СИТС = "" Или Пароль1СИТС = "" Тогда
Сообщить ( "Для продолжения укажите в коде логин и пароль от ИТС." );
Возврат;
КонецЕсли;

КодПриглашения = "inviteCode < &execution &_eventId &username &password /login;" + ИдентификаторСессии2 +
"?service=https%3A%2F%2Fusers.v8.1c.ru%2Fdistribution%2Fpublic%2Fsecurity_check%3B" + ИдентификаторСессии1 ;

СоединениеHTTP3 = Новый HTTPСоединение ( "login.1c.ru" , , , , , , Новый ЗащищенноеСоединениеOpenSSL ());

ЗаголовкиЗапроса1 = Новый Соответствие ;
ЗаголовкиЗапроса1 . Вставить ( "Cookie" , ИдентификаторСессии2 );
ЗаголовкиЗапроса1 . Вставить ( "Content-Type" , "application/x-www-form-urlencoded;" );

ЗаголовкиЗапроса2 = Новый Соответствие ;
ЗаголовкиЗапроса2 . Вставить ( "Cookie" , ИдентификаторСессии1 );

&НаКлиенте
Функция СтруктураURI (Знач СтрокаURI ) Экспорт

СтрокаURI = СокрЛП ( СтрокаURI );

// Схема
Схема = "" ;
ТекущаяПозиция = Найти ( СтрокаURI , "://" );
Если ТекущаяПозиция > 0 Тогда
Схема = НРег ( Лев ( СтрокаURI , ТекущаяПозиция - 1 ));
СтрокаURI = Сред ( СтрокаURI , ТекущаяПозиция + 3 );
КонецЕсли;

// Строка соединения и путь на сервере
СтрокаСоединения = СтрокаURI ;
ПутьНаСервере = "" ;
ТекущаяПозиция = Найти ( СтрокаСоединения , "/" );
Если ТекущаяПозиция > 0 Тогда
ПутьНаСервере = Сред ( СтрокаСоединения , ТекущаяПозиция + 1 );
СтрокаСоединения = Лев ( СтрокаСоединения , ТекущаяПозиция - 1 );
КонецЕсли;

// Авторизация и имя сервера
СтрокаАвторизации = "" ;
ИмяСервера = СтрокаСоединения ;
ТекущаяПозиция = Найти ( СтрокаСоединения , "@" );
Если ТекущаяПозиция > 0 Тогда
СтрокаАвторизации = Лев ( СтрокаСоединения , ТекущаяПозиция - 1 );
ИмяСервера = Сред ( СтрокаСоединения , ТекущаяПозиция + 1 );
КонецЕсли;

// Логин и пароль
Логин = СтрокаАвторизации ;
Пароль = "" ;
ТекущаяПозиция = Найти ( СтрокаАвторизации , ":" );
Если ТекущаяПозиция > 0 Тогда
Логин = Лев ( СтрокаАвторизации , ТекущаяПозиция - 1 );
Пароль = Сред ( СтрокаАвторизации , ТекущаяПозиция + 1 );
КонецЕсли;

// Host, port
Host = ИмяСервера ;
Port = "" ;
ТекущаяПозиция = Найти ( ИмяСервера , ":" );
Если ТекущаяПозиция > 0 Тогда
Host = Лев ( ИмяСервера , ТекущаяПозиция - 1 );
Port = Сред ( ИмяСервера , ТекущаяПозиция + 1 );
КонецЕсли;

РезультатЗапроса = Новый Структура ;
РезультатЗапроса . Вставить ( "Схема" , Схема );
РезультатЗапроса . Вставить ( "Логин" , Логин );
РезультатЗапроса . Вставить ( "Пароль" , Пароль );
РезультатЗапроса . Вставить ( "ИмяСервера" , ИмяСервера );
РезультатЗапроса . Вставить ( "Хост" , Host );
РезультатЗапроса . Вставить ( "Порт" , ?( Port <> "" , Число ( Port ), Неопределено));
РезультатЗапроса . Вставить ( "ПутьНаСервере" , ПутьНаСервере );

&НаКлиенте
Функция ВытащитьЗначениеИзСтроки ( ТекСтрока )

Положение2 = СтрДлина ( ТекСтрока );
Пока Положение2 > 1 Цикл
Если Сред ( ТекСтрока , Положение2 , 1 ) = """" Тогда
Прервать;
КонецЕсли;
Положение2 = Положение2 - 1 ;
КонецЦикла;

Положение1 = Положение2 - 1 ;
Пока Положение1 > 1 Цикл
Если Сред ( ТекСтрока , Положение1 , 1 ) = """" Тогда
Прервать;
КонецЕсли;
Положение1 = Положение1 - 1 ;
КонецЦикла;

Возврат Сред ( ТекСтрока , Положение1 + 1 , Положение2 - Положение1 - 1 );

Читайте также: