Ruby - 从亲戚打开绝对URL

时间:2014-08-27 10:57:08

标签: ruby url nokogiri relative open-uri

我使用open-uri和nokogiri构建了一个web scraper ruby​​脚本,我对这一切都很陌生但是它们都适用于我需要提取数据的几个网站,其源代码中包含完整的URL ,除了使用相对URL的一个。

脚本的作用是打开页面,构建要打开的页面数组,然后通过css(而不是xpath)提取数据。

如何强制脚本在它们相对的实例中使用完整的URL,它一直困扰我一段时间,我似乎无法让它运行

就我而言,我认为我需要在推送网址的时候添加一些东西,有人可以指点我正确的方向吗?非常感谢!谢谢!

require 'open-uri'
require 'nokogiri'

PAGE_URL = "http://www.OMMITED.co.uk"

page = Nokogiri::HTML(open(PAGE_URL, "User-Agent" => “OMMITED“))

links = page.css("a")

links_array = Array.new

links.each{|link|
        url = link['href'].nil? ? 'empty' : link['href']
        if url.include? 'category'  and !url.include? '/all'
                links_array.push url
        end
}

1 个答案:

答案 0 :(得分:0)

tl;博士:在底部简短回答。

好的,假设您有一个名为@url的类变量,其中包含当前页面的完全限定URL:

require 'uri'

def full_url(rel, url)
  return rel if rel.match /^[\w]*:\/\//
  uri = URI(url)
  if rel[0] == '/'
    "#{uri.scheme}://#{uri.host}#{rel}"
  else
    path = uri.path.split('/')[0..-2].select{|m| !m.empty?}.join('/')
    "#{uri.scheme}://#{uri.host}/#{path}/#{rel}"
  end
end

然后你可以打电话:

links_array.push full_url(url, @url)

您可以将该方法放在同一个类或某个帮助器类中。它使用Ruby URI库查找完全限定URL的相关部分,然后从相对路径构造一个新部分。

如果相对路径以'/'开头,它应该在主机之后直接显示。

如果它不以'/'开头,那么它需要与当前页面位于同一个虚拟目录中。因此,如果当前页面是:

http://www.host.com/aaa/bbb/ccc

,相对路径为:

ddd

然后输出应该是:

http://www.host.com/aaa/bbb/ddd

但是,如果相对路径是:

/ddd

然后输出应该是:

http://www.host.com/ddd

代码:

uri.path.split('/')[0..-2].select{|m| !m.empty?}.join('/')

获取完整URL的路径,将其拆分为'/',给出一个数组(['aaa','bbb', 'ccc']),然后删除最后一个元素。 (['aaa','bbb'])。选择删除任何空白元素,然后连接再次将其拼接。 ("aaa/bbb"

OR

你可以用无聊的方式做到这一点:

require 'uri'

URI.join("http://www.host.com/aaa/bbb/ccc", "/ddd").to_s
# => "http://www.host.com/ddd" 

URI.join("http://www.host.com/aaa/bbb/ccc", "ddd").to_s
# => "http://www.host.com/aaa/bbb/ddd" 

给出你的代码:

links.each{|link|
    url = link['href'].nil? ? 'empty' : link['href']
    if url.include? 'category'  and !url.include? '/all'
            links_array.push url
    end
}

我会重写为:

links.each do |link|
  url = link['href'].nil? ? 'empty' : link['href']
  if url.include? 'category' && !url.include? '/all'
    full_url = URI.join(PAGE_URL, url).to_s 
    puts full_url
    links_array << url
    puts links_array.inspect
  end
end

注意:从风格上讲,多行块应该使用do / end而不是{}。缩进应该是两个空格。括号内不应有空格。 &lt;&lt;&lt;运营商比推动更受青睐。始终使用&amp;&amp;在条件而不是and,其优先级低得多并且可能导致问题。请参阅Github风格指南:

https://github.com/styleguide/ruby

puts根据您的评论存在,希望能帮助您弄清楚您的阵列没有表现的原因。应该是,根据你放在那里的代码。我更喜欢使用调试器gem。 (或者如果你使用的是Ruby 2.x,那就是byebug)