将http://添加到URL仍会被解释为不完整的URL

时间:2014-10-08 00:22:39

标签: ruby

我编写了一个抓取任何http或https网站标题的脚本,如果我没有指定自己,我想添加一个将协议添加到URL开头的功能。由于某种原因,它仍然将完成的URL作为无效URL读取并抛出错误。

def headers(hosts)
uri = URI.parse(hosts)
http = Net::HTTP.new(uri.host, uri.port)

if !uri.scheme
    uri = "http://#{uri}"
    puts uri

elsif uri.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
else
    false
end


begin
    Timeout::timeout(8) do
        http.start do
            resp = http.head('/')

            puts "#{resp.code} #{resp.message}"
            resp.each { |k, v| puts "#{k.capitalize}: #{v}" }
            puts "\n"

            http.finish
        end
    end

rescue SocketError
    puts "\nInvalid hostname: #{uri}"

rescue Timeout::Error
    puts "\n#{uri} doesn't seem to exist. Did you type the URL correctly?"

rescue Errno::ECONNREFUSED
    puts "\nERROR: #{uri}; Connection refused!"
end

end


begin
headers(ARGV[0])

rescue Interrupt
puts "\n"
end

你应该能够在脚本的早期看到; if!uri.scheme,我添加了put uri。我想确保我正确地创建了URL,所以我添加了它来测试。现在,比方说,我运行脚本并尝试从google.com抓取标题。该脚本在其前面添加了http://,并确定它放置:http://google.com。但它并没有以某种方式正确解释它。尝试http://google.com有效,但尝试使用google.com并添加http://则不行。我想了解原因。感谢。

2 个答案:

答案 0 :(得分:1)

您有两个错误:一,您没有将url字符串重新解析为对象。第二,如果添加了架构,则不会创建新的HTTP对象。尝试这样的事情:

if !uri.scheme
  uri = URI.parse "http://#{uri}"
end

http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == 'https'
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

答案 1 :(得分:0)

问题

由于uri不包含字符串,因此它包含URI::HTTP对象:

uri = URI.parse("http://www.ruby-lang.org/")
p uri
# => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>

初始化http时,您在Net::HTTP变量中使用此功能。您只需使用新URI创建一个新的Net::HTTP对象。

另一种选择

我注意到这是一个简单任务的代码。以下是使用rest-client的替代方法:

RestClient.get("http://www.google.com/").headers

这也适用于https或没有方案。