Отметим, что канал извлекает из документа анализатор RSS, а наша программа печатает название канала. Кроме того, метод доступа items
формирует список элементов канала, то есть статей, а мы распечатываем их заголовки.
Понятно, что результат меняется со временем; когда я запускал эту программу, она напечатала вот что:
Title: Mars Today Top Stories
1 NASA Mars Picture of the Day: Lava Levees
2 NASA Mars Global Surveyor TES Dust And Temperature Maps 25 June - 2 July 2006
3 Mars Institute Core Team Arrives at the HMP Research Station on Devon Island
4 Assessment of NASA's Mars Architecture 2007-2016
5 NASA Mars Picture of the Day: Rush Hour
Есть также возможность генерировать документы в формате RSS (листинг 15.5). Для этого нужно инвертировать показанную выше процедуру.
Листинг 15.5. Создание RSS-канала
require 'rss'
feed = RSS::Rss.new("2.0")
chan = RSS::Rss::Channel.new
chan.description = "Feed Your Head"
chan.link = "http://nosuchplace.org/home/"
img = RSS::Rss::Channel::Image.new
img.url = "http://nosuchplace.org/images/headshot.jpg"
img.title = "Y.T."
img.link = chan.link
chan.image = img
feed.channel = chan
i1 = RSS::Rss::Channel::Item.new
i1.title = "Once again, here we are"
i1.link = "http://nosuchplace.org/articles/once_again/"
i1.description = "Don't you feel more like you do now than usual?"
i2 = RSS::Rss::Channel::Item.new
i2.title = "So long, and thanks for all the fiche"
i2.link = "http://nosuchplace.org/articles/so_long_and_thanks/"
i2.description = "I really miss the days of microfilm..."
i3 = RSS::Rss::Channel::Item.new
i3.title = "One hand clapping"
i3.link = "http://nosuchplace.org/articles/one_hand_clapping/"
i3.description = "Yesterday I went to an amputee convention..."
feed.channel.items << i1 << i2 << i3
puts feed
Большая часть этой программы понятна без слов. Мы создаем канал в формате RSS 2.0 (с пустыми элементами channel
и image
), а потом с помощью методов доступа добавляем данные. Элемент image
ассоциируется с элементом channel
, а последний — с самим RSS-каналом.
Наконец, мы создаем последовательность статей и помещаем их в канал. Отметим, что необходимо добавлять статьи именно по отдельности. Возникает искушение пойти по более простому пути:
feed.channel. items = [i1,i2,i3]
но такое решение работать не будет. Почему-то в классе Channel
нет акцессора items=
. Можно было бы написать items[0] = i1
и т.д., или то же самое в цикле. Наверное, есть и другие способы добиться нужного результата, но представленное выше решение вполне годится.
У библиотеки rss
есть еще много возможностей, но не все в данный момент хорошо документированы. Если вы не сможете найти то, что вам нужно, в качестве последнего средства обратитесь к исходным текстам.
Многие предпочитают не RSS, a Atom. Библиотека rss
не умеет работать с этим форматом, но есть прекрасная (хотя и не стандартная) библиотека feedtools
. Мы рассмотрим ее в следующем разделе.
15.2.2. Библиотека feedtools
Библиотека feedtools
(распространяемая в виде gem-пакета) — плод работы Боба Амана (Bob Aman). Она более или менее единообразно работает с обоими форматами RSS и Atom и сохраняет все данные в общем внутреннем формате (основанном преимущественно на Atom). В нее встроены собственные средства для работы с IRI, так что явно включать библиотеки net/http
или open-uri
не требуется.
Вот простой пример, эквивалентный первому примеру из предыдущего раздела:
require 'feed_tools'
URL = "http://www.marstoday.com/rss/mars.xml"
feed = FeedTools::Feed.open(URL)
puts "Description: #{feed.title}\n"
feed.entries.each_with_index {|x,i| puts "#{i+1} #{x.title}" }
Этот вариант короче и яснее предыдущего. Некоторые вещи не так очевидны, например у объекта feed
нет явного метода channel
. Однако такие методы, как title
и description
можно вызывать непосредственно для объекта feed
, поскольку канал может быть только один.
Ниже показано, как читать новости из канала в формате Atom:
require 'feedtools'
URL = "http://www.atomenabled.org/atom.xml"
feed = FeedTools::Feed.open(URL)
puts "Description: #{feed.title}\n"
feed.entries.each_with_index {|x,i| puts "#{i+1} #{x.title}" }
Обратите внимание — изменился только сам URL! Это замечательно, поскольку мы можем обрабатывать каналы независимо от формата. Результат, естественно, похож на то, что мы видели раньше:
Description: AtomEnabled.org
1 AtomEnabled's Atom Feed
2 Introduction to Atom
3 Moving from Atom 0.3 to 1.0
4 Atom 1.0 is Almost Final
5 Socialtext Supports Atom
Хочу еще раз предостеречь вас: не тратьте впустую ресурсы сервера, принадлежащего поставщику канала. Реальное приложение должно кэшировать содержимое канала, а если вы занимаетесь просто тестированием, лучше создайте собственный канал. Библиотека feedtools
поддерживает довольно развитый механизм кэширования в базе данных, которого должно хватить для большинства применений.
Читать дальше
Конец ознакомительного отрывка
Купить книгу