gifts2017

Полноценный RSS parser (полная поддержка RSS 0.9x, RSS 2.0, RSS 1.0, and Atom 0.3) средствами 1С (без DOM)

Опубликовал Влад Косилов (kosilov) в раздел Программирование - Практика программирования

RSS парсер позволяет разобрать XML сообщение форматов RSS 0.9x, RSS 2.0, RSS 1.0, and Atom 0.3 и разложить в таблицу новостей, где каждое поле исходного XML файла займет свою строго определенную колонку в таблице.
При кажущейся простоте задачи, она сильно усложняется обилием несовместимых форматов RSS лент, а кроме этого фривольным названием тэгов в новостях и каналах.
Проверить работу парсера теперь можно прямо из обработки

Данный RSS парсер портирован на язык 1С из PHP. 
Исходным кодом RSS парсера послужил

"Project: MagpieRSS: a simple RSS integration tool 
File: rss_parse.inc - parse an RSS or Atom feed return as a simple object."

author Kellan Elliott-McCrea
version 0.7a
license GPL
The lastest version of MagpieRSS can be obtained from:
http://magpierss.sourceforge.net

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

 Библиотека функций парсера помещена во внешнюю обработку в модуль объекта.

Проверить работу парсера теперь можно прямо из обработки (обновленаCool)

Как использовать:

Скопируйте функции из обработку в конфигурация в общий модуль (или куда вам нравиться).

Файл xml необходимо предварительно скачать на локальный (сетевой диск) например такой функцией:

 

Функция ЗапроситьФайлыССервера(СерверИсточник, СтрПарам, ИмяВходящегоФайла, ИспользоватьПрокси=ложь, ПроксиАдрес = "", ПроксиПользователь= "", ПроксиПароль = "", ПроксиПорт="")  экспорт
   
Попыток = 10;

~Проба:если Не ИспользоватьПрокси тогда
       
HTTP = Новый HTTPСоединение(СерверИсточник);
    иначе
       
ПроксиСервер = новый ИнтернетПрокси();
       
ПроксиСервер.Пользователь = ПроксиПользователь;
       
ПроксиСервер.Пароль = ПроксиПароль;
       
ПроксиСервер.Установить("http",ПроксиАдрес,ПроксиПорт);
       
HTTP = новый HTTPСоединение(СерверИсточник,,,,ПроксиСервер);
    конецесли;
    Попытка

       
HTTP.Получить("", ИмяВходящегоФайла);
        возврат истина;
    Исключение
       
ДСообщить(ОписаниеОшибки());
        если
Попыток>0 тогда
           
Попыток = Попыток-1;
        перейти
~Проба;
        конецесли;
        Если
ТипЗнч(HTTP) <> Тип("HTTPСоединение") тогда
           
Сообщить(НСтр("ru = 'Соединение с сервером не установлено'; en = 'Conection with server not established'; ge = 'Conection with server not established'"));
            возврат неопределено;
        конецесли;
    КонецПопытки;
    возврат истина;
КонецФункции

После того как файл скачен его можно парсить.

Для этого воспользуйтей оригинальной функцией:

MagpieRSS(ИмяФайлаXML), где в качестве параметра передается имя файл с полным путем.

Но данная функция возвращает не очень удобный объект для работы.

Поэтому рекомендую воспользоваться моей функцией, которая сама вызовет MagpieRSS, а возвращенный объект преобразует в таблицуЗначений.

ПолучитьТаблицуНовостей(СоответствиеПолей, ФайлRSS)

Второй параметр, файл XML с полным именем (включающим путь), а первый  - соответствие, где:

Ключ: ТипТэга[ChannelTag/NewsTag] + "_" + ПолеИсточника

Значение: Структура(DBField:ПолеНовостиБД, Date:Признак необходимости конвертирования в дату)

Смысл соответствия в том,  что в него вы помещаете все поля (тэги), которые вам надо получить из канала иновостей. Тэги бывают общие для канала и тогда перед именем ставим "ChannelTag_" и новостные и тогда перед именем ставим "NewsTag_". 

Структура содержит два элемента. 

Первый - строка - название колонки, куда будет помещаться контент из тэга ключа 

если для разных тэгов источника указана одинаковая колонка, то информация суммируется через пробел (кроме тэгов даты).

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

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

Получить список тэгов канала можно моей следующей функцией:

 

Процедура FillSourceTags()
   
HTMLtext    =   "";
   
ТекURL = СтрЗаменить(URL, "http://", "");
   
ЗапроситьФайлыССервера(ТекURL,"", КаталогВременныхФайлов()+"rss.tmp");
   
rss = RSSParser.MagpieRSS(КаталогВременныхФайлов()+"rss.tmp");
   
ComplianceTags = новый ТаблицаЗначений;
   
ComplianceTags.Колонки.Добавить("TagType");
   
ComplianceTags.Колонки.Добавить("SourceTag");
   
ComplianceTags.Колонки.Добавить("ContentExample");


   
Индекс=0;
   
ТэгиКанала = новый ТаблицаЗначений;
   
ТэгиКанала.Колонки.Добавить("Tag");
   
ТэгиКанала.Колонки.Добавить("Content_Example");
    Для каждого
item из rss.channel цикл
       
ПолучитьТэгиРекурсивно(item, ТэгиКанала);
    КонецЦикла;
   
ТэгиНовости = новый ТаблицаЗначений;
   
ТэгиНовости.Колонки.Добавить("Tag");
   
ТэгиНовости.Колонки.Добавить("Content_Example");
    Для каждого
item из rss.items цикл
       
ПолучитьТэгиРекурсивно(item, ТэгиНовости);
    КонецЦикла;
   
ComplianceTags.Очистить();
    Для каждого
Эл из ТэгиКанала цикл
       
НовСтр = ComplianceTags.Добавить();
       
НовСтр.TagType = "ChannelTag";
       
НовСтр.SourceTag = Эл.Tag;
       
НовСтр.ContentExample = Эл.Content_Example;
    КонецЦикла;
    Для каждого
Эл из ТэгиНовости цикл
       
НовСтр = ComplianceTags.Добавить();
       
НовСтр.TagType = "NewsTag";
       
НовСтр.SourceTag = Эл.Tag;
       
НовСтр.ContentExample = Эл.Content_Example;
    КонецЦикла;
    возврат
ComplianceTags;
КонецПроцедуры

Функция
ПолучитьТэгиРекурсивно(Элемент, МассивТэгов)
    если
ТипЗнч(Элемент) = Тип("Соответствие") или ТипЗнч(Элемент) = Тип("Массив") тогда
        Для каждого
Эл из Элемент цикл
           
ПолучитьТэгиРекурсивно(Эл, МассивТэгов);
        КонецЦикла;
        возврат неопределено;
    иначеесли
ТипЗнч(Элемент) = Тип("КлючИЗначение") тогда
       
Знч = ПолучитьТэгиРекурсивно(Элемент.Значение,МассивТэгов);
        если
Знч<>неопределено и МассивТэгов.Найти(Элемент.Ключ,"Tag")=неопределено тогда
               
НовСтр = МассивТэгов.Добавить();
               
НовСтр.Tag = Элемент.Ключ;
               
НовСтр.Content_Example = Знч;
        конецесли;
        возврат неопределено;
    иначе
        возврат
Элемент;
    конецесли;
КонецФункции

Функцию Преобразования строки в дату (используется в функции ПолучитьТаблицуНовостей) брать здесь http://infostart.ru/public/70017/

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

Для компактного хранения результатов хэш функции можно переводить результат в строку такой функцией

Работа парсера еще не достаточно протестирована поэтому если обнаружите ошибки вработе, напишите пожалуйстасюда или на мой Email(kosilov_DOG_inbox.ru).

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
RSS parser
.epf 32,98Kb
30.10.14
64
.epf 32,98Kb 64 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Алексей Ситников (SiAl) 13.05.10 13:09
Здорово. Но смысл? Есть много более приятных читалок. Если только для саморазвития?
2. Влад Косилов (kosilov) 13.05.10 21:06
(1)Это конечно здорово, что ты воспринял моюобработку читалкой.
Но это совсемне так.
Обработка - просто пример использования и совсем не читалка.
Для меня парсер - побочный продукт входящий в состав аналитической базы данных.
3. Сергей (seermak) 14.05.10 12:30
{Обработка.RSSparser.МодульОбъекта(888,7)}: Переменная не определена (RSSParser)
rss = <<?>>RSSParser.MagpieRSS(ФайлRSS); (Проверка: Сервер)
просто на вскидку - ошибка
4. Влад Косилов (kosilov) 15.05.10 03:24
(3) Исправил. Эти функции остались в общем модуле и у меня ошибки не было при проверке. Сейчас перенес их в обработку.
5. Сергей (seermak) 15.05.10 10:15
пропали надписи на кнопках Получить поля Получить новости
6. Влад Косилов (kosilov) 15.05.10 10:46
(5) Исправил, но это какой-то глюк 1С. При открытии обработки в конфигураторе, где установлен другой набор языков локализации надписи стираются.
7. Pavel Amadi (pako_amadi) 07.12.11 11:02
Не плохо. особенно при интеграции с внешними веб приложениями
8. Евгений Золотарев (ИТ-Терминал) 19.05.16 08:41
Добрый день

Источник <rss version="2.0">
При попытке "Получить поля" выходит ошибка:
{Форма.RSSparser.Форма(119)}: Ошибка при вызове метода контекста (Получить): Ошибка работы с Интернет: Couldn't resolve host name

что можете посоветовать, куда "копнуть"?
9. Евгений Золотарев (ИТ-Терминал) 19.05.16 08:42
На всякий случай версия платформы - 1С:Предприятие 8.3 (8.3.5.1383)
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа