Tag: HTTP

Ruby 1.8.7, Open-Uri and HTTPS (SSL) websites

Using open-uri Ruby library to open http websites is really easy:

begin
  io_thing = open(self.check_url.to_s)
  io_thing.status[0] == '200'
rescue Exception => e
  false
end

Things get itchy when we want to visit a HTTPS (SSL) self-signed website. Some of them have them corrupted (or expired). Open-uri raises an exception when it occures one of them. To skip certificates testing and get the page we need to turn off certificates verification:

module OpenSSL
  module SSL
    remove_const :VERIFY_PEER
  end
end
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

However remember to do this carefully, because this can we a security thread to your software.

Sprawdzanie poprawności URLi z wykorzystaniem Pythona i urllib2

Dzisiaj dla odmiany od Rubiego, krótki poradnik dot. sprawdzania dostępności strony WWW z wykorzystaniem Pythona i biblioteki urllib2.

Wstęp

Zdarza się, że potrzebujemy wiedzieć czy url jaki wprowadza użytkownik jest poprawny i czy taka strona w ogóle istnieje. Może się to przydać chociażby do walidacji pola url w modelu usera. Dzięki temu użytkownik nie będzie mógł wprowadzić przez pomyłkę adresu który nie istnieje.

Metoda

Metoda jest całkiem prosta - wystarczy odpytać żądaniem HEAD nasz url, sprawdzić co zostanie zwrócone i ewentualnie przechwycić wyjątki. Warto zauważyć, że w poniższym kodzie dokonałem pewnego uproszczenia. Mianowicie, przechwytuję część błędów nadając im ręcznie wartość 404. Tak naprawdę te błędy należałoby obsłużyć w inny sposób, ponieważ niekoniecznie oznaczają to, że podana strona nie istnieje. Poniżej opis tego co który wyjątek oznacza:

  • urllib2.HTTPError - błędy z serwera (404, 500, 403, itd)
  • urllib2.URLError - nieprawidłowy URL (nie istnieje taki adres lub błąd w składni)
  • Exception - całe inne zło tego świata :)

Najpierw zaimportujmy sobie co nam potrzeba i ustalmy jaki URL sprawdzamy:

import urllib2
from urllib2 import URLError

uri = "http://onet.pl"

No i sprawdzamy:

def uri_status( uri):
  if len(uri) == 0: return '404'
  try:
      request = urllib2.Request(uri,  None, {'User-agent': 'Mozilla/5.0'})
      request.get_method = lambda : 'HEAD'
      response = urllib2.urlopen(request)
      return '200'
  except urllib2.HTTPError, e:
      return e.code
  except urllib2.URLError, e:
      return '404'
  except Exception, e:
      return '404'

print uri_status(uri)

Kod metody i jej wywołanie:

def uri_status( uri):
  if len(uri) == 0: return False
  try:
      request = urllib2.Request(uri,  None, {'User-agent': 'Mozilla/5.0'})
      request.get_method = lambda : 'HEAD'
      response = urllib2.urlopen(request)
      return '200'
  except urllib2.HTTPError, e:
      return e.code
  except urllib2.URLError, e:
      return '404'
  except Exception, e:
      return '404'

print uri_status(uri)

Podajemy user_agenta (przeglądarkę), ponieważ niektóre serwisy nie chcą (lub robią to błędnie) odpowiadają na żądania.

UPDATE

Warto ustawić także timeout dla połączeń - ponieważ połączenia bez ustalonego timeoutu mogą trwać w nieskończoność. Nie można tego jednak zrobić z poziomu urllib2 a jedynie dla socketów:

import socket
import urllib2

# timeout w sekundach
timeout = 10
socket.setdefaulttimeout(timeout)

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑