提取与Nokogiri的RSS链接

时间:2014-01-09 15:38:51

标签: ruby xpath rss screen-scraping nokogiri

我正在使用Nokogiri从网页中提取RSS链接。但是,由于某些网站的HTML有绝对路径和其他网站,我想这样做,如果网站有相对路径,那么它将成为绝对路径。

这是我的代码:

require 'nokogiri'
require 'simple-rss'
require 'open-uri'


ARGV.map! { |http| "http://#{http}"}
ARGV.each do |website|
doc = Nokogiri::HTML(open(website))
rss_path = doc.xpath("//link[@type=\"application/rss+xml\"]").map do |link|
    if link['href'] =~ /^http:\/\/[a-z]*\..*\//i
        puts link['href']
    else
        puts "#{website}#{link['href']}"
    end
end

因此,如果我在命令行,我会输入类似

的内容
ruby rss.rb 8gramgorilla.com rubyweekly.com

这个代码适用于rubyweekly.com,它有一个相对路径的RSS,但8gramgorilla.com有一个绝对路径,所以我希望它只是立即输出,而不是http://8gramgorilla.com/http://8gramgorilla.com/feed作为输出。基本上,正在发生的是IF语句被忽略,它立即被发送到else语句。

3 个答案:

答案 0 :(得分:2)

if语句未被忽略,它正在评估为false。您的正则表达式为/^http:\/\/[a-z]*\..*\//i,因此它正在查找http://后跟任意数量的a-z(或.,因为零a-z也将匹配)。但网站网址为http://8gramgorilla.com,第一个字符为数字8,不在a-z范围内。

对此最直接的解决方法是将正则表达式更改为包含数字,可能类似于/^http:\/\/[\da-z]*\..*\//i(其中已添加\d)。

您可以更多地简化正则表达式,或者只是检查一下url是否与http://匹配就足够了。

更强大的解决方案是正确解析相关网址,可能使用Addressable gemURI module in Ruby’s standard lib

答案 1 :(得分:0)

不需要if,只需要:

require 'uri'
puts URI.join(website, link['href']).to_s

答案 2 :(得分:0)

检测纽约时报http://www.nytimes.com的RSS源:

<link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml">

我会使用以下内容从href链接标记中提取application/rss+xml值:

require 'nokogiri'
require 'httparty'
url = 'http://www.nytimes.com'
resp = HTTParty.get(url)
doc = Nokogiri::HTML(resp.body)
feed = doc.css("link[type='application/rss+xml']").map{|link|link[:href]}.first

哪会返回网站的RSS Feed值:

http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml

注意,如果网站application/rss+xml标记,代码将只返回nil