Как получить RSS-канал в формате xml для скрипта ruby

Я использую следующий ruby-скрипт из этот лихой виджет, который извлекает RSS-канал, анализирует его и отправляет который проанализировал заголовок и описание виджета.

require 'net/http'
require 'uri'
require 'nokogiri'
require 'htmlentities'

news_feeds = {
  "seattle-times" => "http://seattletimes.com/rss/home.xml",
}

Decoder = HTMLEntities.new

class News
  def initialize(widget_id, feed)
    @widget_id = widget_id
    # pick apart feed into domain and path
    uri = URI.parse(feed)
    @path = uri.path
    @http = Net::HTTP.new(uri.host)
  end

  def widget_id()
    @widget_id
  end

  def latest_headlines()
    response = @http.request(Net::HTTP::Get.new(@path))
    doc = Nokogiri::XML(response.body)
    news_headlines = [];
    doc.xpath('//channel/item').each do |news_item|
      title = clean_html( news_item.xpath('title').text )
      summary = clean_html( news_item.xpath('description').text )
      news_headlines.push({ title: title, description: summary })
    end
    news_headlines
  end

  def clean_html( html )
    html = html.gsub(/<\/?[^>]*>/, "")
    html = Decoder.decode( html )
    return html
  end

end

@News = []
news_feeds.each do |widget_id, feed|
  begin
    @News.push(News.new(widget_id, feed))
  rescue Exception => e
    puts e.to_s
  end
end

SCHEDULER.every '60m', :first_in => 0 do |job|
  @News.each do |news|
    headlines = news.latest_headlines()
    send_event(news.widget_id, { :headlines => headlines })
  end
end

Пример rss-канала работает правильно, потому что URL-адрес предназначен для файла xml. Однако я хочу использовать это для другого RSS-канала, который не предоставляет фактический XML-файл. Этот rss-канал, который мне нужен, находится по адресу http://www.ttc.ca/RSS/Service_Alerts/index.rss Кажется, это ничего не отображает в виджете. Вместо использования "http://www.ttc.ca/RSS/Service_Alerts/index.rss", я также попробовал "http://www.ttc.ca/RSS/Service_Alerts/index.rss?format=xml" и "view-source:http://www.ttc.ca/RSS/Service_Alerts/index.rss", но безуспешно. Кто-нибудь знает, как я могу получить фактические данные xml, связанные с этим rss-каналом, чтобы я мог использовать их с этим рубиновым скриптом?


person user1893354    schedule 17.12.2013    source источник
comment
Вы должны принять ответ diego.greyrobot, поскольку он был правильным, чтобы он мог получить свои заслуженные баллы.   -  person Paul Brunache    schedule 06.11.2014


Ответы (1)


Вы правы, эта ссылка не предоставляет обычный XML, поэтому этот скрипт не будет работать при его разборе, поскольку он написан специально для анализа примера XML. RSS-канал, который вы пытаетесь проанализировать, предоставляет RDF XML, и вы можете использовать Rubygem: RDFXML для разбора.

Что-то типа:

require 'nokogiri'
require 'rdf/rdfxml'

rss_feed = 'http://www.ttc.ca/RSS/Service_Alerts/index.rss'

RDF::RDFXML::Reader.open(rss_feed) do |reader|
  # use reader to iterate over elements within the document
end

Отсюда вы можете попробовать научиться использовать RDFXML для извлечения нужного содержимого. Я бы начал с проверки объекта читателя на наличие методов, которые я мог бы использовать:

puts reader.methods.sort - Object.methods

Это распечатает собственные методы читателя, ищите тот, который вы могли бы использовать для своих целей, например reader.each_entry

Чтобы продолжить копание, вы можете проверить, как выглядит каждая запись:

reader.each_entry do |entry|
  puts "----here's an entry----" 
  puts entry.inspect
end

или посмотрите, какие методы вы можете вызвать для записи:

reader.each_entry do |entry|
  puts "----here's an entry's methods----" 
  puts entry.methods.sort - Object.methods
  break
end

Я смог грубо найти некоторые заголовки и описания, используя эту халтуру:

RDF::RDFXML::Reader.open('http://www.ttc.ca/RSS/Service_Alerts/index.rss') do |reader|
  reader.each_object do |object|
    puts object.to_s if object.is_a? RDF::Literal
  end
end

# returns:

# TTC Service Alerts
# http://www.ttc.ca/Service_Advisories/index.jsp

#      TTC Service Alerts.

# TTC.ca
# http://www.ttc.ca
# http://www.ttc.ca/images/ttc-main-logo.gif
# Service Advisory
# http://www.ttc.ca/Service_Advisories/all_service_alerts.jsp#Service+Advisory

# 196 York University Rocket route diverting northbound via Sentinel, Finch due to a collision that has closed the York U Bus way.
# - Affecting: Bus Routes: 196 York University Rocket
# 2013-12-17T13:49:03.800-05:00
# Service Advisory (2)
# http://www.ttc.ca/Service_Advisories/all_service_alerts.jsp#Service+Advisory+(2)

# 107B Keele North route diverting northbound via Keele, Lepage due to a collision that has closed the York U Bus way.
# - Affecting: Bus Routes: 107 Keele North
# 2013-12-17T13:51:08.347-05:00

Но я не мог быстро найти способ узнать, какой из них был заголовком, а какой описанием :/

Наконец, если вы все еще не можете найти, как извлечь то, что хотите, начните новый вопрос с этой информацией.

Удачи!

person DiegoSalazar    schedule 17.12.2013
comment
Спасибо, это очень полезно - person user1893354; 18.12.2013