На одном проекте - клиент попросил отображать в программе данные, которые выдаю специализированные сайта в формате RSS - Что делать !?
Первым делом, взглянув на ссылки, подумал что - обычный XML, сейчас его разложу и быстренько загружу в базу, но:
таким образом, написав небольшой код, который получает ссылку, далее XMLФайл.Прочитать() на одном сайте проходил на ура (этот пример я описывал в статье: Чтение данных с сайта в формате XML и загрузка в 1С ), а вот второй сайт, и третий тоже, при попытке прочитать() выдавали:
решил попробовать на rss других известных сайтов - 80% из проверяемых выдавали ошибку
Код получился таким(в принципе код универсальный, но возможно что-то придется подпилить):
Код 1C v 8.3
Процедура ПрочитатьRSS(ИсточникRSS)
url = ИсточникRSS. UrlRSS;
Если Найти( url, ".ru" ) > 0 Тогда urlСервер = Лев( url, Найти( url, ".ru" ) + 2 ) ;
ИначеЕсли Найти( url, ".com" ) > 0 Тогда urlСервер = Лев( url, Найти( url, ".com" ) + 3 ) ;
ИначеЕсли Найти( url, ".org" ) > 0 Тогда urlСервер = Лев( url, Найти( url, ".org" ) + 3 ) ;
ИначеЕсли Найти( url, ".info" ) > 0 Тогда urlСервер = Лев( url, Найти( url, ".info" ) + 4 ) ;
ИначеЕсли Найти( url, ".pro" ) > 0 Тогда urlСервер = Лев( url, Найти( url, ".pro" ) + 3 ) ;
КонецЕсли ;
Если Лев( url, 5 ) = "https" Тогда
ssl = Новый ЗащищенноеСоединениеOpenSSL( неопределено , неопределено ) ;
ТекАдрес = СтрЗаменить( url, urlСервер, "" ) ; Сервер = СтрЗаменить( urlСервер, "https://" , "" ) ;
Соединение = Новый HTTPСоединение( Сервер, , , , ,
5 ,
ssl
) ;
Иначе
ТекАдрес = СтрЗаменить( url, urlСервер, "" ) ; Сервер = СтрЗаменить( urlСервер, "http://" , "" ) ;
Соединение = Новый HTTPСоединение( Сервер) ;
КонецЕсли ;
Заголовки = Новый Соответствие;
Заголовки. Вставить( "host" , Сервер) ;
Запрос = Новый HTTPЗапрос( ТекАдрес, Заголовки) ;
Ответ = Соединение. Получить( Запрос) ;
Если Ответ. КодСостояния = 200 Тогда
Содержимое= Ответ. ПолучитьТелоКакСтроку( ) ;
Содержимое = СтрЗаменить( Содержимое, "<br/>" , "|" ) ;
Содержимое = СтрЗаменить( Содержимое, "<![CDATA[" , "" ) ; Содержимое = СтрЗаменить( Содержимое, "]]>" , "" ) ;
Содержимое = СтрЗаменить( Содержимое, Символы. ПС, "" ) ; Содержимое = СтрЗаменить( Содержимое, Символы. ВК, "" ) ;
Содержимое = СтрЗаменить( Содержимое, Символы. ВТаб, "" ) ; Содержимое = СтрЗаменить( Содержимое, Символы. Таб, "" ) ;
Содержимое = СтрЗаменить( Содержимое, "><" , ">" + Символы. ПС+ "<" ) ;
RegExp = Новый COMОбъект( "VBScript.RegExp" ) ;
RegExp. IgnoreCase = Ложь ;
RegExp. Global = Истина ;
RegExp. MultiLine = Истина ;
RegExp. Pattern = "<[^>]*>" ;
ЭтоЗапись= Ложь ;
Для н= 1 По СтрЧислоСтрок( Содержимое) Цикл
обрТекст= СтрПолучитьСтроку( Содержимое, н) ;
Если обрТекст = "<item>" Тогда
ЗаписьСтр = Новый Структура( ) ; ЭтоЗапись= Истина ; Продолжить;
ИначеЕсли обрТекст = "</item>" Тогда
Запрос = Новый Запрос;
Запрос. Текст =
"ВЫБРАТЬ
| ДанныеRSS.Ссылка
|ИЗ
| Справочник.ДанныеRSS КАК ДанныеRSS
|ГДЕ
| ДанныеRSS.ИсточникRSS =ИсточникRSS
| И ДанныеRSS.link ПОДОБНОlink" ;
Запрос. УстановитьПараметр( "link" , "%" + ЗаписьСтр. link+ "%" ) ;
Запрос. УстановитьПараметр( "ИсточникRSS" , ИсточникRSS) ;
РезультатЗапроса = Запрос. Выполнить( ) . Выбрать( ) ;
Если РезультатЗапроса. Следующий( ) Тогда
Иначе
НовЭлем = Справочники. ДанныеRSS. СоздатьЭлемент( ) ;
ЗаполнитьЗначенияСвойств( НовЭлем, ЗаписьСтр) ;
НовЭлем. ИсточникRSS = ИсточникRSS;
НовЭлем. Записать( ) ;
КонецЕсли ;
ЭтоЗапись= Ложь ; Продолжить;
КонецЕсли ;
Если ЭтоЗапись Тогда
Если Найти( обрТекст, "title>" ) > 0 и Найти( обрТекст, "/title>" ) > 0 Тогда
обрТекст = СтрЗаменить( обрТекст, "title" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "<>" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "</>" , "" ) ;
ЗаписьСтр. Вставить( "Наименование" , СокрЛП( обрТекст) ) ;
КонецЕсли ;
Если Найти( обрТекст, "link>" ) > 0 и Найти( обрТекст, "/link>" ) > 0 Тогда
обрТекст = СтрЗаменить( обрТекст, "link" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "<>" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "</>" , "" ) ;
ЗаписьСтр. Вставить( "link" , СокрЛП( обрТекст) ) ;
КонецЕсли ;
Если Найти( обрТекст, "description>" ) > 0 и Найти( обрТекст, "/description>" ) > 0 Тогда
обрТекст = СтрЗаменить( обрТекст, "description" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "<>" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "</>" , "" ) ;
обрТекст= RegExp. Replace( обрТекст, "" ) ;
ЗаписьСтр. Вставить( "desc" , СокрЛП( обрТекст) ) ;
КонецЕсли ;
Если Найти( обрТекст, "pubDate>" ) > 0 и Найти( обрТекст, "/pubDate>" ) > 0 Тогда
обрТекст = СтрЗаменить( обрТекст, "pubDate" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "<>" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "</>" , "" ) ;
ЗаписьСтр. Вставить( "pubDate" , ПреобразоватьRFC822КДате0 ( СокрЛП( обрТекст) ) ) ;
КонецЕсли ;
Если Найти( обрТекст, "enclosure" ) > 0 Тогда
обрТекст = СтрЗаменить( обрТекст, """ " , "" ) ; обрТекст = СтрЗаменить( обрТекст, "<enclosure url=" , "" ) ;
обрТекст = СтрЗаменить( обрТекст, "<enclosure url=" , "" ) ; обрТекст = СтрЗаменить( обрТекст, "type=image/png length=/>" , "" ) ;
ЗаписьСтр. Вставить( "img" , СокрЛП( обрТекст) ) ;
КонецЕсли ;
КонецЕсли ;
КонецЦикла ;
КонецЕсли ;
КонецПроцедуры
Процедура ПроверкаRSS() Экспорт
Запрос = Новый Запрос;
Запрос. Текст =
"ВЫБРАТЬ
| ИсточникиRSS.Ссылка КАК Ссылка
|ИЗ
| Справочник.ИсточникиRSS КАК ИсточникиRSS
|ГДЕ
| ИсточникиRSS.Использовать
| И ДОБАВИТЬКДАТЕ(ИсточникиRSS.ДатаПоследнегоОбновления, СЕКУНДА, ИсточникиRSS.ПериодОбновленияВСекундах) <ТекДата" ;
Запрос. УстановитьПараметр( "ТекДата" , ТекущаяДата( ) ) ;
РезультатЗапроса = Запрос. Выполнить( ) ;
ВыборкаДетальныеЗаписи = РезультатЗапроса. Выбрать( ) ;
Пока ВыборкаДетальныеЗаписи. Следующий( ) Цикл
ПрочитатьRSS( ВыборкаДетальныеЗаписи. Ссылка) ;
ТекОб = ВыборкаДетальныеЗаписи. Ссылка. ПолучитьОбъект( ) ;
ТекОб. ДатаПоследнегоОбновления = ТекущаяДата( ) ;
ТекОб. Записать( ) ;
КонецЦикла ;
КонецПроцедуры
Функция ПреобразоватьRFC822КДате0(ДатаВФорматеRFC822) Экспорт
КопияСтроки = ДатаВФорматеRFC822;
СтруктураДаты = Новый Структура( "Год,Месяц,День,Час,Минута,Секунда" , "" , "" , "" , "" , "" , "" ) ;
Месяцы = Новый Структура( "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec" , "01" , "02" , "03" , "04" , "05" , "06" , "07" , "08" , "09" , "10" , "11" , "12" ) ;
Для каждого КлючИЗначение Из Месяцы Цикл
Позиция = Найти( КопияСтроки, КлючИЗначение. Ключ) ;
Если Позиция > 0 Тогда
СтруктураДаты. Месяц = КлючИЗначение. Значение;
Прервать ;
КонецЕсли ;
КонецЦикла ;
Состояние = 0 ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 1 " , ", 01 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 2 " , ", 02 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 3 " , ", 03 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 4 " , ", 04 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 5 " , ", 05 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 6 " , ", 06 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 7 " , ", 07 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 8 " , ", 08 " ) ;
КопияСтроки = СтрЗаменить( КопияСтроки, ", 9 " , ", 09 " ) ;
Для ш= 0 По СтрДлина( КопияСтроки) Цикл
ТекущийСимвол = Сред( КопияСтроки, ш, 1 ) ;
ТекСимволЦифра= ЭтоЦифра( ТекущийСимвол) ;
Если ТекСимволЦифра И Состояние = 0 Тогда
СтруктураДаты. День = СтруктураДаты. День + ТекущийСимвол;
Состояние = 1 ;
ИначеЕсли ТекСимволЦифра И Состояние = 1 Тогда
СтруктураДаты. День = СтруктураДаты. День + ТекущийСимвол;
Состояние = 2 ;
ИначеЕсли ТекСимволЦифра И Состояние = 2 Тогда
СтруктураДаты. Год = СтруктураДаты. Год + ТекущийСимвол;
Состояние = 3 ;
ИначеЕсли ТекСимволЦифра И Состояние = 3 Тогда
СтруктураДаты. Год = СтруктураДаты. Год + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = " " И Состояние = 3 Тогда
Состояние = 4 ;
ИначеЕсли ТекСимволЦифра И Состояние = 4 Тогда
СтруктураДаты. Час = СтруктураДаты. Час + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = ":" И Состояние = 4 Тогда
Состояние = 5 ;
ИначеЕсли ТекСимволЦифра И Состояние = 5 Тогда
СтруктураДаты. Минута = СтруктураДаты. Минута + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = ":" И Состояние = 5 Тогда
Состояние = 6 ;
ИначеЕсли ТекСимволЦифра И Состояние = 6 Тогда
СтруктураДаты. Секунда = СтруктураДаты. Секунда + ТекущийСимвол;
ИначеЕсли ТекущийСимвол = " " И Состояние = 6 Тогда
Прервать ;
КонецЕсли ;
КонецЦикла ;
Попытка
Результат = Дата( СтруктураДаты. Год+ СтруктураДаты. Месяц+ СтруктураДаты. День
+ СтруктураДаты. Час+ СтруктураДаты. Минута+ СтруктураДаты. Секунда) ;
Исключение
Результат = Неопределено ;
КонецПопытки ;
Возврат Результат;
КонецФункции
Функция ЭтоЦифра(Символ) Экспорт
Если ( КодСимвола( Символ) > = 48 ) И ( КодСимвола( Символ) < = 57 ) Тогда Возврат Истина ; Иначе Возврат ложь ; КонецЕсли ;
КонецФункции
Функция ПолучитьСимвол(КопияСтроки, ш)
Возврат Сред( КопияСтроки, ш, 1 ) ;
КонецФункции