Программист 1с
twitter email rss
  • Home
  • Полезности
    • Мобильное приложение курьера
    • MailChimp + УТ 11.
    • 1с-sms
    • Pharma-MPD
    • Зуботехническая лаборатория
  • Блог
  • Партнеры
  • Команда
    • Услуги
    • Опыт
    • Отзывы
    • Контакты
  • Поддержка
    • Инструкция
    • Redmine






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

Для хранения html-страниц в конфигурации был выбран объект встроенного языка ФорматированныйДокумент. В конфигурации находится справочник «Элементы» с реквизитом «Описание» (тип ХранилищеЗначения), в котором будет храниться форматированный документ.

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

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

Для загрузки страницы используем HTTPСоединение и его метод Получить(). После загрузки html-страницы во временный файл происходит чтение его как текста и обход строки в цикле для поиска наличия картинок на странице. Наличие картинки определяется вхождением текста «<img». По вхождению в строку значения «src=» определяется адрес расположения картинки по значению, которое храниться в переменной РасположениеФайла . После определения адреса картинки с помощью HTTPСоединение происходит его скачивание во временный файл. После получения картинки происходит подмена в исходном html-коде источника картинки на значения типа «image1», «image2», которые хранятся в нашей структуре вложений. В конце обхода html кода мы готовы к формированию форматированного документа.

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

Функция ЗагрузитьССайта(СсылкаНаСайт,КешКартинок) Экспорт
    СтруктураАдреса = РазобратьАдресСайта(СсылкаНаСайт);
    АдресСайта = СтруктураАдреса.HTTPСервер;
    ПутьНаСайте = СтруктураАдреса.HTTPАдресСкрипта;

    ПроксиСервер = Неопределено;

    //Грузим сам ХТМЛ
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("html");

    HTTPСервис = Новый HTTPСоединение(АдресСайта,,,,ПроксиСервер,Ложь);
    ПравильностьВыполнения = Истина;

    Попытка
        HTTPСервис.Получить(ПутьНаСайте, ИмяВременногоФайла);
    Исключение
        Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
        ПравильностьВыполнения = Ложь;
        Возврат Неопределено;
    КонецПопытки;

    //Разбор ХТМЛ
    ЧтениеХТМЛ = Новый ЧтениеТекста;
    ЧтениеХТМЛ.Открыть(ИмяВременногоФайла, КодировкаТекста.UTF8);
    НашаСтрока = ЧтениеХТМЛ.Прочитать();
    ТекстХТМЛ = НашаСтрока;

    ФорматированныйДокумент = Новый ФорматированныйДокумент;
    СтруктураВложений = Новый Структура;
    //Парсим картинки
    Сч = 0;
    НомерФайла = 0;
    РазборКартинки = Ложь;
    Пока Сч <= СтрДлина(НашаСтрока)  Цикл
        Если НРег(Сред(НашаСтрока,Сч,4)) =  "<img" Тогда
            РазборКартинки = Истина;
            //Началась картинка
            Пока Сч <= СтрДлина(НашаСтрока) И РазборКартинки  Цикл
                Если НРег(Сред(НашаСтрока,Сч,5)) =  "src=""" Тогда
                    //Сразу перескакиваем к адресу
                    Сч = Сч + 5;
                    РасположениеФайла = "";
                    ТекСимвол = Сред(НашаСтрока,Сч,1);
                    Пока ТекСимвол <> """" Цикл
                        РасположениеФайла = РасположениеФайла + ТекСимвол;
                        Сч = Сч + 1;
                        ТекСимвол = Сред(НашаСтрока,Сч,1);
                    КонецЦикла;
                    //Загрузка файла
                    НомерФайла = НомерФайла + 1;

                    Если КешКартинок.Получить(РасположениеФайла) = Неопределено Тогда
                        ИмяВременногоФайла = ПолучитьИмяВременногоФайла("");
                        СтруктураАдреса = РазобратьАдресСайта(РасположениеФайла);
                        АдресСайта = СтруктураАдреса.HTTPСервер;
                        ПутьНаСайте = СтруктураАдреса.HTTPАдресСкрипта;
                        HTTPСервис = Новый HTTPСоединение(АдресСайта,,,,ПроксиСервер,Ложь);
                        Попытка
                            HTTPСервис.Получить(ПутьНаСайте, ИмяВременногоФайла);
                        Исключение
                            Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
                            ПравильностьВыполнения = Ложь;
                            Возврат Неопределено;
                        КонецПопытки;
                        НоваяКартинка = Новый Картинка(ИмяВременногоФайла);
                        КешКартинок.Вставить(РасположениеФайла, НоваяКартинка);
                    Иначе
                        НоваяКартинка = КешКартинок.Получить(РасположениеФайла);
                    КонецЕсли;

                    //Подмена в хтмл картинок на другой сорс
                    ИмяНовогоФайла = "image" + Формат(НомерФайла, "ЧЦ=3; ЧВН=");
                    ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,РасположениеФайла, ИмяНовогоФайла);
                    СтруктураВложений.Вставить(ИмяНовогоФайла, НоваяКартинка);
                    РазборКартинки = Ложь;
                КонецЕсли;
                Сч = Сч + 1;
            КонецЦикла;
        КонецЕсли;
        Сч = Сч + 1;
    КонецЦикла;
    ФорматированныйДокумент.УстановитьHTML(ТекстХТМЛ,СтруктураВложений);

    Возврат ФорматированныйДокумент;
КонецФункции

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

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

.

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

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

Похожие записи:

  1. Печать html-страницы с помощью IE
  2. Форматированный документ.
  3. Выгрузка форматированного документа 1С на свой сайт
  4. Параллельная загрузка, фоновые задачи.
  5. Слияние форматированных документов
  • Александр Кунташов

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

    2. Обычно отдельные элементы дизайна страниц одного и того же сайта повторяются, соответственно, повысить эффективность скачивания нескольких страниц одного и того же сайта подряд можно добавив кэширование картинок в соответствии, в котором ключем будет URL картинки, а значением — путь к временному файлу скачанной картинки.

    • Андрей Данилюк

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

    • Андрей Данилюк

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

  • VitaliyTokarev

    Есть один косяк.
    Если адрес картинки относительный без адреса сервера…
    Я сделал так:
    Если КешКартинок.Получить(РасположениеФайла) = Неопределено Тогда  ИмяВременногоФайла = ПолучитьИмяВременногоФайла(«»); //ЕСЛИ КАРТИНКА ИМЕЕТ ПУТЬ ОТНОСИТЕЛЬНЫЙ, АдресСайта пустой, тогда ошибки… СтруктураАдресаКартинки = РазобратьАдресСайта(РасположениеФайла); АдресСайтаКартинки = СтруктураАдресаКартинки.HTTPСервер; Если ПустаяСтрока(АдресСайтаКартинки) Тогда АдресСайтаКартинки = АдресСайта; КонецЕсли; ПутьНаСайтеКартинки = СтруктураАдресаКартинки.HTTPАдресСкрипта; HTTPСервисКартинки = Новый HTTPСоединение(АдресСайтаКартинки,,,,ПроксиСервер,Ложь); Попытка HTTPСервис.Получить(ПутьНаСайтеКартинки, ИмяВременногоФайла); Исключение Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное); ПравильностьВыполнения = Ложь; Возврат Неопределено; КонецПопытки; НоваяКартинка = Новый Картинка(ИмяВременногоФайла); КешКартинок.Вставить(РасположениеФайла, НоваяКартинка); Иначе НоваяКартинка = КешКартинок.Получить(РасположениеФайла); КонецЕсли;

    • Андрей Данилюк

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

  • Александр Крынецкий

    Функция РазобратьАдресСайта() отрабатывает неверное, если URL начинается с https://

    • Андрей Данилюк

      Спасибо за исправление.

  • Mihail Chichagov

    Где можно скачать конфигурацию? Ссылка выше не работает.

    • Андрей Данилюк

      Ссылка работает. Нажмите «Сохранить как» на ссылке.

← Рассылка писем.
Определение координат объекта на Google maps →

Новости

  • Работаем с Opendatabot из 1с
  • Сокращаем ссылки в 1с
  • Загрузка данных из Google spreadsheet в 1с
  • Формирование скриншотов сайтов в 1с
  • Удаление старой номенклатуры

Подписка

Copyright © 2021 danila.org.ua
Умные решения для вашего бизнеса