Выгрузка HTML описаний с картинками (Base64) товаров на сайт/интернет-магазин/B2B, разберем регулярное выражение получения тега body, ПолучитьHTML, ФорматированныйДокумент

24.02.21

Интеграция - Сайты и интернет-магазины

Редактор HTML платформы 1С простой и очень удобный для небольших задач, однако ПолучитьHTML возвращает отдельно картинки и отдельно целиком HTML страницу со ссылкой на имена этих картинок, что неудобно для отправки в базу данных сайта/интернет-магазина/веб-приложения/B2B. Разберем на открытом коде, как решить эту проблему, напишем универсальную функцию получения значения любого тега HTML на регулярных выражениях. Бонусом - возможность редактировать теги HTML в текстовом режиме.

В интернет-магазинах/сайтах/веб-приложениях/B2B  отображение характеристик товаров, картинок и текстовых описаний обычно оформляется в отдельных блоках . Однако, в текстовых описаниях иногда требуется использование HTML тегов, таких как: выделить жирным, подчеркнуть, заголовки, размер шрифта, вставить поясняющие картинки внутри описания и оформить список. Для решения этой задачи вполне достаточно функций стандартного HTML редактора платформы 1С, который просто внедряется в любую форму. 

В нашем конструкторе веб-приложений EDIbot (подсистема для 1С для создания Dashboard, B2B) тоже возникла необходимость использования в ячейках внутреннего HTML оформления шаблона, покажем на примере:

 

 

Или вот как эта карточка выглядит в вебе -   https://jsonwebapp.com/regexp/json, ссылка на JSON для песочницы.

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

Функция ПолучитьHTML()  возвращает нам HTML страницу со ссылками внутри неё на ключи картинок ("image001") и заполняет структуру вложений.  

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="format-detection" content="telephone=no" />
<style type="text/css">
body{margin:0;padding:8px;}
p{line-height:1.15;margin:0;white-space:pre-wrap;}
ol,ul{margin-top:0;margin-bottom:0;}
img{border:none;}
li>p{display:inline;}
</style>
</head>
<body>
<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>
</body>
</html>

Как выяснилось, нам это неудобно, и требуется: 

1.Получить значение тега <body> из HTML (без самого тега body), который нам возвращает ПолучитьHTML.

2.Преобразовать получаемые картинки в base64 и заменить на него ключи в теле HTML.

 

Давайте реализуем функцию, которая получает значение произвольного тега HTML без самого тега - ПолучитьЗначениеТегаHTML(HTML, "body").

Проще всего для этого использовать регулярные выражения, в данном случае, нам подойдёт - <body[^>]*>((.|\n)*)<\/body>.

Давайте разберем его:

  1. <body[^>]*> - означает, что нам нужно найти в тексте <body>, причем после слова body может идти любой символ, кроме >. Используем жадный алгоритм (без ?), квантификатор *, т.е. нам подходит ноль или более букв после слова body. В итоге алгоритм найдет и <body>, и <body style="max-width: 1920px;background-color: rgb(166,166,166);">
  2. ((.|\n)*) - означает, что нам подходит любой символ или перевод строки после тега <body>, используем также жадный алгоритм. Скобочки нужны, чтобы выделить значение в отдельную группу (без слова body), которую мы легко сможем получить используя SubMatches. Кстати, если надо найти все теги <p>, то нужно из жадного сделать ленивый, добавив знак вопроса - ((.|\n)*?).  
  3. <\/body> - означает, что шаблон завершается тегом </body>, символ \ экранирует символ /. 

Попробовать его работу можно на сайте - https://regex101.com/r/MCgzCo/1/

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

Функция ПолучитьЗначениеТегаHTML(HTML, Тег) экспорт
	
	Результат = HTML;
	
	РегулярноеВыражение = _ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение("<"+Тег+"[^>]*>((.|\n)*)<\/"+Тег+">", Истина, Истина, Истина);			
	
	Выражения = РегулярноеВыражение.Execute(HTML);	
	
	Если Выражения.Count()>0 И Выражения.Item(0).SubMatches.Count()>0 Тогда		
		Результат = СокрЛП(Выражения.Item(0).SubMatches.Item(0));		
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

 

 

В результате обработки этой функцией нашего HTML мы получаем текст:

<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>

Здесь вставленная картинка описывается ключом ("image001") и отправка такой информации на сайт/интернет-магазин/веб-приложение приведёт к отображению страницы без картинки. Чтобы исправить такое положение дел, мы воспользуемся заменой ключей картинок на их значение в формате base64, собственно вот реализация такой процедуры: 

Процедура ЗаменитьКартинкиНаBase64(HTML, ВложенияHTML, ОбратноеДействие=Ложь) экспорт
	
	Для Каждого Вложение Из ВложенияHTML Цикл
		
		Картинка = Вложение.Значение; ИмяКартинки = Вложение.Ключ;
		
		Попытка
			ПрефиксBase64 = ПолучитьПрефиксBase64(Картинка.Формат());
		Исключение
			Продолжить;
		КонецПопытки;
		
		Если ПустаяСтрока(ПрефиксBase64) Тогда
			Продолжить;
		КонецЕсли;	
		
		ДвоичныеДанныеФайла = Картинка.ПолучитьДвоичныеДанные();
		
		Если ОбратноеДействие Тогда
			HTML = СтрЗаменить(HTML, "src="""+ПрефиксBase64+Base64Строка(ДвоичныеДанныеФайла)+"""", "src="""+ИмяКартинки+"");
		Иначе	
			HTML = СтрЗаменить(HTML, "src="""+ИмяКартинки+"", "src="""+ПрефиксBase64+Base64Строка(ДвоичныеДанныеФайла)+"""");
		КонецЕсли;	
			
	КонецЦикла;	
	
КонецПроцедуры

 

Теперь мы можем построить нашу итоговую универсальную функцию по сохранению HTML, которая на вход получает форму, объект, вложения HTML и реквизиты формы (типа структура), используемые для HTML редактирования.

Процедура СохранитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты)экспорт
    
    Если СтруктураВложенийHTML=Неопределено Тогда
        СтруктураВложенийHTML = Новый Структура();
    КонецЕсли;
    
    Для Каждого Реквизит Из Реквизиты Цикл
        
        ВложенияHTMLРеквизита = Новый Структура();
        
        Форма[Реквизит.Значение].ПолучитьHTML(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);
        
        СтруктураВложенийHTML.Вставить(Реквизит.Ключ, ВложенияHTMLРеквизита);
        
        //сохраним только тело
        Объект[Реквизит.Ключ] = ПолучитьЗначениеТегаHTML(Объект[Реквизит.Ключ], "body");
        
        ЗаменитьКартинкиНаBase64(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);    
        
    КонецЦикла;    
    
КонецПроцедуры   

 

Пример вызова функции, например, из ПередЗаписьюНаСервере: _ВебАппHTML.СохранитьHTMLПоля(ЭтаФорма, ТекущийОбъект, ВложенияHTML, Новый Структура("_ОписаниеHTML", "_ОписаниеHTMLФорма"));

_ОписаниеHTML - это реквизит метаданных типа неограниченная строка

_ОписаниеHTMLФорма - это реквизит формы типа ФорматированныйДокумент.

 

 

Отлично, мы сохранили с Вами данные, а теперь при открытии в следующий раз их нужно восстановить, т.е. выполнить обратное действие по замене картинок на их ключи. Зачем? А чтобы мы могли потом редактировать теги HTML без пролистывания большого значения base64.

 

Для этого реализуем универсальную функцию  - ВосстановитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты).

Процедура ВосстановитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты) экспорт
	
	Если НЕ ТипЗнч(СтруктураВложенийHTML)=Тип("Структура") Тогда
		СтруктураВложенийHTML = Новый Структура();
	КонецЕсли;	
	
	ВложенияHTMLРеквизита = Неопределено;
	Для Каждого Реквизит Из Реквизиты Цикл
	
		СтруктураВложенийHTML.Свойство(Реквизит.Ключ, ВложенияHTMLРеквизита);
		Если НЕ ТипЗнч(ВложенияHTMLРеквизита)=Тип("Структура") Тогда
			ВложенияHTMLРеквизита = Новый Структура();
		КонецЕсли;	
		
		HTML = Объект[Реквизит.Ключ];
		
		ЗаменитьКартинкиНаBase64(HTML, ВложенияHTMLРеквизита, Истина);
		
		Форма[Реквизит.Значение].УстановитьHTML(HTML, ВложенияHTMLРеквизита); 
		
	КонецЦикла;
	
КонецПроцедуры

 

Бонусом, как и обещал, мы теперь с Вами можем переходить вот в такой режим редактирования:

 

 

Все это легко сделать с помощью разработанных ранее универсальных функций:

&НаСервере
Процедура УправлениеРедактированиемHTML()
	
	Если Объект._РежимРедактированияТекста Тогда
		
		ВложенияHTMLРеквизита = Новый Структура();
		_ОписаниеHTMLФорма.ПолучитьHTML(Объект._ОписаниеHTML, ВложенияHTMLРеквизита);

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

 

UPD.

Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции

 

Надеюсь, моя публикация была Вам полезна и сэкономит Ваше время, ссылка на все публикации SizovE.

Подписывайтесь на мой канал (наверху), будет много интересного бесплатного контента :)

SizovE

См. также

API-интеграция 1С с маркетплейсами ОЗОН, WildBerries, Я.Маркет, СберМегаМаркет, Стройландия, Леруа Мерлен, Hoff, AliExpress для УТ11, КА2, ERP2, УНФ, БП3, Розница, УТ10, УПП1.3

Сайты и интернет-магазины Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Беларусь Россия Управленческий учет Платные (руб)

Модуль для интеграции с маркетплейсами ОЗОН, WildBerries, Я.Маркет, СберМегаМаркет, Стройландия, Леруа Мерлен, Hoff, AliExpress. При помощи расширения поддерживаются следующие методы: обмен остатками товаров, обмен ценами, обработка заказов, печать стикеров, загрузка отчетов комиссионеров по API (в том числе Я.Маркет). Подходит для конфигураций Беларуси. Поддержка искусственного интелекта GigaChat

59990 руб.

05.09.2023    8314    126    74    

78

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    15936    13    18    

13

Оплата покупок "Долями" в 1С:Розница 2.3 (для работы с сервисом dolyame.ru)

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 2 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Готовое интеграционное решение для оплаты покупок Долями в 1C:Розница 2.3. Реализовано в виде расширения. Интеграция сервиса dolyame.ru для приема платежей в рассрочку.

18000 руб.

19.12.2023    1546    12    3    

10

Обмен данными с сайтом. БП 3.0

Оптовая торговля Розничная торговля Сайты и интернет-магазины Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Обмен данными с сайтом на платформе 1С:Битрикс (и подобными) для 1С: Бухгалтерия предприятия 3.0.

12000 руб.

18.03.2019    31528    111    100    

64

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    17896    6    15    

12

Универсальный парсер интернет-магазинов

Оптовая торговля Розничная торговля Сайты и интернет-магазины Платформа 1С v8.3 Управляемые формы 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Управленческий учет Платные (руб)

С того времени, как я начал парсить сайты, прошло много лет. За это время я спарсил более 100 сайтов и записал эти товары в 1С. В итоге на свет появился универсальный парсер, который поможет Вам спарсить интернет-магазин и при этом не написать ни строчки кода.

9600 руб.

19.10.2018    52202    220    99    

111
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. AneJIbcuH 37 22.02.21 17:16 Сейчас в теме
Подскажите, а тут что за функция?
_ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение(
2. SizovE 263 24.02.21 10:19 Сейчас в теме
(1) Спасибо, забыл выложить
Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции
Показать
3. dimasts 22 16.04.21 23:13 Сейчас в теме
Как быть с картинками имеющими адрес такого типа?
"blob:applewebdata://97a79a97-c02b-4585-8339-fd38316054e7/44b6636c-7eab-494a-a09e-8731d7ee2e92"
Такой адрес имеют все картинки перетасканные в ПолеФорматированногоДокумента
Они не сохраняются при ПолученииHtml и даже при сохранении в ХранилищеЗначений, но агружаются при новом открытии документа.

при перезагрузке ТонкогоКлиента картинки исчезают.
4. SizovE 263 17.04.21 07:40 Сейчас в теме
(3) А Вы пробовали перетаскивать в другие редакторы? Например, зайти сюда, перетащить картинку http://suneditor.com/sample/index.html, посмотреть по кнопке </>, как будет там. Если гуд, то вот Вам как его подключить в одной из моих публикаций https://infostart.ru/1c/articles/1352459/
Оставьте свое сообщение