如何在ruby中检查正确的url协议?

时间:2014-07-28 22:43:40

标签: ruby-on-rails ruby open-uri

我有50,000个网站的列表,我想知道他们有什么样的协议。我拥有的所有网站都有names.com或者像something.com,但没有一个 http://google.com。我确实尝试运行每个并手动检查..

require 'rubygems'

require 'open-uri'
require 'io/console'
require 'open_uri_redirections'
require 'openssl'

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE



filename = "./testfile.txt"
destination = File.open("./11aa.txt", "a")

newArray = Array.new
newArray = IO.readlines(filename)
newArray.each do |url|
begin
    puts "#{url}"
    if open(url,:read_timeout=>2 )
        destination.write "#{url}"      
    end

rescue => e
  puts e.message
end
    end

确实有效,但需要永远完成。我正在寻找更好的算法来检查。

由于

3 个答案:

答案 0 :(得分:1)

“协议”?与用于连接到URL定义的主机的IP协议一样?

require 'uri'

URI.parse('http://foo.com').scheme # => "http"
URI.parse('https://foo.com').scheme # => "https"
URI.parse('ftp://foo.com').scheme # => "ftp"
URI.parse('scp://foo.com').scheme # => "scp"

如果您想知道某个网站是否接受HTTPS与HTTP,我会先检查HTTPS,因为大多数网站都允许使用HTTP:

require 'net/http'

%w[
  example.com
  www.example.com
  mail.google.com
  account.dyn.com
].each do |url|
  begin
    Net::HTTP.start(url, 443, :use_ssl => true) {}
    puts "#{url} is HTTPS"
  rescue
    puts "#{url} is HTTP"
  end
end
# >> example.com is HTTP
# >> www.example.com is HTTP
# >> mail.google.com is HTTPS
# >> account.dyn.com is HTTPS

即使mail.google.com和account.dyn.com是HTTPS,如果您首先测试它们的HTTP,您会看到它们也有该协议。某些站点会将其HTTP请求重定向到其HTTPS服务器,其他站点会同时运行以允许用户决定是否需要HTTP或HTTPS。您可以测试两种协议以确定哪些情况属实。

start不需要块,但通过提供空块,它会在建立后立即自动关闭连接。

站点不一定在端口80和443上运行他们的Web服务。因此,假设连接应该是其中一个端口不一定是正确的,并且如果他们使用不同的端口可能会给你带来不好的结果。 8080和8081也经常被使用,所以也应该检查它们。

此外,站点可能会响应端口,但其内容可能是指向您希望您使用的真实端口的重定向,因此您还需要考虑是否应该只关心连接是否成功,或者看看在HTTPd标头内部,或者实际读取返回的整个页面,并在它是软件重定向的情况下解析它。

换句话说,连接成功并不足以告诉您网站希望您使用的内容,您还必须进行其他测试。

答案 1 :(得分:0)

您最关心哪种协议? HTTPS优先于HTTP吗?有些是两者都有,有些是重定向(http://www.google.com是302)

如果你不关心它是哪一个,那么首先使用http,因为它可能更快。所以调用它应该快得多。

另外,我将read_timeout降至1甚至500毫秒。如果某个网站在这段时间内没有响应,它可能也会死亡(我们正在谈论一个简单的回复,而不是完全下载DOM的所有资产)。

答案 2 :(得分:0)

  

要求'open-uri'

def correct_url_protocol(single_url)
    puts "-----------------------In correct_url_protocol--------------------------"

        begin
         good_link = "http://www.#{single_url}"
            if open(good_link, read_timeout: 3,:allow_redirections => :all)
                "http://www.#{single_url}"
            else 
                "https://www.#{single_url}"
            end 
        rescue => e
            exp = e.message
            if exp.match("redirection forbidden")
                good_link = "https://www.#{single_url}"
                good_link

                end
            puts e.message
            good_link
        end 
end

我认为这是我创造的最佳方法。让我知道是否更好。