programing

Ruby에 URL이 있는지 확인

itsource 2021. 1. 17. 10:52
반응형

Ruby에 URL이 있는지 확인


Ruby를 사용하여 URL이 있는지 확인하려면 어떻게해야합니까?

예를 들어, URL의 경우

https://google.com

결과는 사실 이어야 하지만 URL의 경우

https://no.such.domain

또는

https://stackoverflow.com/no/such/path

결과는 거짓 이어야합니다


Net :: HTTP 라이브러리를 사용하십시오 .

require "net/http"
url = URI.parse("http://www.google.com/")
req = Net::HTTP.new(url.host, url.port)
res = req.request_head(url.path)

이 시점 에서 요청 결과를 포함 res하는 Net :: HTTPResponse 객체가 있습니다. 그런 다음 응답 코드를 확인할 수 있습니다.

do_something_with_it(url) if res.code == "200"

참고 : https기반 URL 을 확인하려면 use_ssl속성이 다음 true같아야합니다 .

require "net/http"
url = URI.parse("https://www.google.com/")
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true
res = req.request_head(url.path)

이에 대한 답변이 늦어 죄송합니다. 그러나 이것이 더 나은 답변이라고 생각합니다.

이 질문을 보는 방법에는 세 가지가 있습니다.

  1. URL이 있는지 엄격한 확인
  2. URL 정확성을 요청하는지 확인
  3. 올바르게 요청하고 서버가 올바르게 응답 할 수 있는지 확인하십시오.

1. URL이 존재하는지 엄격한 확인

반면 200수단 다른 상태 코드를 응답하는 URL (즉, URL이 존재)에 대한 서버 응답이 URL이 존재하지 않는다고하지 수단을한다는 것을. 예를 들어 응답 302 - redirected은 URL이 존재하고 다른 URL로 리디렉션됨을 의미합니다. 탐색하는 동안 302여러 번 200최종 사용자 와 동일하게 작동합니다 . URL이있는 경우 반환 될 수있는 다른 상태 코드는 500 - internal server error입니다. 결국 URL이 존재하지 않으면 응용 프로그램 서버가 요청을 처리하여 대신 단순히 반환하는 방법은 404 - not found무엇입니까?

따라서 실제로 URL이 존재하지 않는 경우는 두 가지뿐입니다. 서버가 존재하지 않거나 서버가 존재하지만 지정된 URL 경로가 존재하지 않는 경우입니다. 따라서 URL이 존재하는지 확인하는 유일한 방법은 서버가 응답하고 반환 코드가 404가 아닌지 확인 하는 것입니다. 다음 코드는이를 수행합니다.

require "net/http"
def url_exist?(url_string)
  url = URI.parse(url_string)
  req = Net::HTTP.new(url.host, url.port)
  req.use_ssl = (url.scheme == 'https')
  path = url.path if url.path.present?
  res = req.request_head(path || '/')
  res.code != "404" # false if returns 404 - not found
rescue Errno::ENOENT
  false # false if can't find the server
end

2. URL 정확성을 요청하는지 확인

그러나 대부분의 경우 URL이 존재하는지 확인하는 데 관심이 없지만 액세스 할 수 있는지 확인합니다 . 다행히도 클라이언트 오류 (따라서 페이지를 올바르게 요청하지 않았거나 권한이 없음을 의미하는 오류)에 대해 설명 하는 HTTP 상태 코드 계열, 즉 계열을 찾습니다 4xx. 이 페이지에 액세스 할 수 있는지 확인하는 좋은 오류입니다. 위키에서 :

4xx 클래스의 상태 코드는 클라이언트가 오류가있는 것으로 보이는 경우를위한 것입니다. HEAD 요청에 응답 할 때를 제외하고 서버는 오류 상황에 대한 설명과 그것이 임시 또는 영구 조건인지 여부를 포함하는 엔티티를 포함해야합니다. 이러한 상태 코드는 모든 요청 방법에 적용 할 수 있습니다. 사용자 에이전트는 포함 된 모든 엔티티를 사용자에게 표시해야합니다.

따라서 다음 코드 는 URL이 있는지 확인하고 액세스 할 수 있습니다 .

require "net/http"
def url_exist?(url_string)
  url = URI.parse(url_string)
  req = Net::HTTP.new(url.host, url.port)
  req.use_ssl = (url.scheme == 'https')
  path = url.path if url.path.present?
  res = req.request_head(path || '/')
  if res.kind_of?(Net::HTTPRedirection)
    url_exist?(res['location']) # Go after any redirect and make sure you can access the redirected URL 
  else
    res.code[0] != "4" #false if http code starts with 4 - error on your side.
  end
rescue Errno::ENOENT
  false #false if can't find the server
end

3. 올바르게 요청하고 서버가 올바르게 응답 할 수 있는지 확인

그냥 같은 4xx가족 확인 당신은 URL에 액세스 할 수있는 경우 5xx서버가 귀하의 요청에 응답 문제가 있다면 가족 검사를. 이 패밀리의 오류는 대부분 서버 자체의 문제이며 해결하기 위해 노력하고 있습니다. 경우 당신은 페이지에 액세스 지금은 정확한 답변을 얻을 수 있어야합니다 , 당신은 확실히 대답에서하지해야 4xx또는 5xx가족, 당신이 리디렉션 된 경우, 올바르게 리디렉션 된 페이지의 답변. (2)와 매우 유사하므로 다음 코드를 사용하면됩니다.

require "net/http"
def url_exist?(url_string)
  url = URI.parse(url_string)
  req = Net::HTTP.new(url.host, url.port)
  req.use_ssl = (url.scheme == 'https')
  path = url.path if url.path.present?
  res = req.request_head(path || '/')
  if res.kind_of?(Net::HTTPRedirection)
    url_exist?(res['location']) # Go after any redirect and make sure you can access the redirected URL 
  else
    ! %W(4 5).include?(res.code[0]) # Not from 4xx or 5xx families
  end
rescue Errno::ENOENT
  false #false if can't find the server
end

Net::HTTP works but if you can work outside stdlib, Faraday is better.

Faraday.head(the_url).status == 200

(200 is a success code, assuming that's what you meant by "exists".)


Simone's answer was very helpful to me.

Here is a version that returns true/false depending on URL validity, and which handles redirects:

require 'net/http'
require 'set'

def working_url?(url, max_redirects=6)
  response = nil
  seen = Set.new
  loop do
    url = URI.parse(url)
    break if seen.include? url.to_s
    break if seen.size > max_redirects
    seen.add(url.to_s)
    response = Net::HTTP.new(url.host, url.port).request_head(url.path)
    if response.kind_of?(Net::HTTPRedirection)
      url = response['location']
    else
      break
    end
  end
  response.kind_of?(Net::HTTPSuccess) && url.to_s
end

ReferenceURL : https://stackoverflow.com/questions/5908017/check-if-url-exists-in-ruby

반응형