我编写了一个抓取任何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://则不行。我想了解原因。感谢。
答案 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
或没有方案。