简体   繁体   中英

Ruby, using Nokogiri and media:thumbnail

I have searched endlessly for a solution to this and I thought i had solved it when I got an image to display. However the thumbnail was only the one stored in the root element. Quite simply this works:

rss = Nokogiri::XML(open('http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml'))
@news = rss.xpath('//item').map do |i|
  {
    'title'       => i.xpath('title').text, 
    'link'        => i.xpath('link').text, 
    'description' => i.xpath('description').text,
    'thumbnail'   => i.xpath('//media:thumbnail').attr('url')
  }
end

But editing the media:thumbnail to reference that item seems to break it:

{
  'title'       => i.xpath('title').text, 
  'link'        => i.xpath('link').text, 
  'description' => i.xpath('description').text,
  'thumbnail'   => i.xpath('media:thumbnail').attr('url')
}

I don't understand why as both elements are identical. Any pointers in the right direction would be appreciated.

Thanks!

Your code breaks at the first element that doesn't have a thumbnail child element. Try this:

@news = rss.xpath('//item').map do |i|
  thumb = i.at_xpath('media:thumbnail').attr('url') if i.at_xpath('media:thumbnail')
  {
    'title' => i.at_xpath('title').text, 
    'link' => i.at_xpath('link').text, 
    'description' => i.at_xpath('description').text,
    'thumbnail' => thumb
  }
end

Now thumbnail will either be the URL if it exists or nil if it doesn't.

Just for comparison, here's some alternate ways to access the nodes using Nokogiri:

require 'ap'
require 'open-uri'
require 'nokogiri'

rss = Nokogiri::XML(open('http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml'))

# check for parsing errors...
puts "Errors exist" if (rss.errors.any?)

# use CSS accessors for simplicity...
news = rss.search('item').map { |i|

  # use CSS's namespace wildcard...
  thumbnail = i.at('media|thumbnail')
  begin
    url = thumbnail['url']
  rescue
    url = ''
  end
  {
    'title'       => i.search('title').text, 
    'link'        => i.search('link').text, 
    'description' => i.search('description').text,
    'thumbnail'   => url
  }
}

ap [*news[0 .. 1], *news[-2 .. -1]]
# >> [
# >>     [0] {
# >>               "title" => "Royal attack 'not down to radios'",
# >>                "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11975280",
# >>         "description" => "Police deny that a car carrying the Prince of Wales was caught up in student protests because of a breakdown in radio communications.",
# >>           "thumbnail" => "http://news.bbcimg.co.uk/media/images/50372000/jpg/_50372715_010819577-1.jpg"
# >>     },
# >>     [1] {
# >>               "title" => "Pope Anglican offer 'dented ties'",
# >>                "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11974543",
# >>         "description" => "Britain's ambassador to the Vatican feared a backlash over the Pope's invitation to Anglicans to switch churches, according to leaked US cables.",
# >>           "thumbnail" => "http://news.bbcimg.co.uk/media/images/48697000/jpg/_48697938_007958675-1.jpg"
# >>     },
# >>     [2] {
# >>               "title" => "Playing defence",
# >>                "link" => "http://news.bbc.co.uk/go/rss/int/news/-/1/hi/programmes/from_our_own_correspondent/9275324.stm",
# >>         "description" => "The friendly face of township where honeymoon bride was killed",
# >>           "thumbnail" => "http://news.bbcimg.co.uk/media/images/50385000/jpg/_50385343_football_afp.jpg"
# >>     },
# >>     [3] {
# >>               "title" => "Newspaper review",
# >>                "link" => "http://www.bbc.co.uk/go/rss/int/news/-/news/uk-11975338",
# >>         "description" => "Papers reflect on attack on royal car",
# >>           "thumbnail" => "http://news.bbcimg.co.uk/media/images/49254000/jpg/_49254932_efb006dc-dd09-47bd-8f2d-37752152f772.jpg"
# >>     }
# >> ]

Notice the use of the CSS namespace wildcard. It can make your life a lot easier if you don't care about namespaces in the document and want to process everything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM