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 dir开发者_StackOverflowection 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.
精彩评论