Python-¿Cómo validar una url en python?(Malformado o no)
malformedurlexception (7)
Tengo url
del usuario y tengo que responder con el HTML extraído.
¿Cómo puedo verificar si la URL está mal formada o no?
Por ejemplo :
url=''google'' // Malformed
url=''google.com'' // Malformed
url=''http://google.com'' // Valid
url=''http://google'' // Malformed
¿Cómo podemos lograr esto?
django url validación regex:
regex = re.compile(
r''^(?:http|ftp)s?://'' # http:// or https://
r''(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?/.)+(?:[A-Z]{2,6}/.?|[A-Z0-9-]{2,}/.?)|'' #domain...
r''localhost|'' #localhost...
r''/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3})'' # ...or ip
r''(?::/d+)?'' # optional port
r''(?:/?|[/?]/S+)$'', re.IGNORECASE)
print re.match(regex, "http://www.example.com") is not None # True
print re.match(regex, "example.com") is not None # False
Aterricé en esta página tratando de encontrar una forma sensata de validar las cadenas como URL "válidas". Comparto aquí mi solución usando python3. No se requieren bibliotecas adicionales.
Consulte https://docs.python.org/2/library/urlparse.html si está usando python2.
Consulte https://docs.python.org/3.0/library/urllib.parse.html si está usando python3 como yo.
import urllib
from pprint import pprint
invalid_url = ''dkakasdkjdjakdjadjfalskdjfalk''
valid_url = ''https://.com''
tokens = [urllib.parse.urlparse(url) for url in (invalid_url, valid_url)]
for token in tokens:
pprint(token)
min_attributes = (''scheme'', ''netloc'') # add attrs to your liking
for token in tokens:
if not all([getattr(token, attr) for attr in min_attributes]):
error = "''{url}'' string has no scheme or netloc.".format(url=token.geturl())
print(error)
else:
print("''{url}'' is probably a valid url.".format(url=token.geturl()))
ParseResult (scheme = '''', netloc = '''', path = ''dkakasdkjdjakdjadjfalskdjfalk'', params = '''', query = '''', fragmento = '''')
ParseResult (scheme = ''https'', netloc = ''.com'', path = '''', params = '''', query = '''', fragmento = '''')
La cadena ''dkakasdkjdjakdjadjfalskdjfalk'' no tiene esquema ni netloc.
'' Home '' es probablemente una URL válida.
Aquí hay una función más concisa:
import urllib
min_attributes = (''scheme'', ''netloc'')
def is_valid(url, qualifying=None):
qualifying = min_attributes if qualifying is None else qualifying
token = urllib.parse.urlparse(url)
return all([getattr(token, qualifying_attr)
for qualifying_attr in qualifying])
En realidad, creo que esta es la mejor manera.
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
val = URLValidator(verify_exists=False)
try:
val(''http://www.google.com'')
except ValidationError, e:
print e
Si establece verify_exists
en True
, realmente verificará que la URL exista; de lo contrario, solo comprobará si está formada correctamente.
editar: ah sí, esta pregunta es un duplicado de esto: ¿cómo puedo verificar si existe una URL con los validadores de Django?
Una versión True o False, basada en la respuesta @DMfll:
try:
# python2
from urlparse import urlparse
except:
# python3
from urllib.parse import urlparse
a = ''http://www.cwi.nl:80/%7Eguido/Python.html''
b = ''/data/Python.html''
c = 532
d = u''dkakasdkjdjakdjadjfalskdjfalk''
def uri_validator(x):
try:
result = urlparse(x)
return result.scheme and result.netloc and result.path
except:
return False
print(uri_validator(a))
print(uri_validator(b))
print(uri_validator(c))
print(uri_validator(d))
Da:
True
True
False
True
Usa el paquete de validadores :
>>> import validators
>>> validators.url("http://google.com")
True
>>> validators.url("http://google")
ValidationFailure(func=url, args={''value'': ''http://google'', ''require_tld'': True})
>>> if not validators.url("http://google"):
... print "not valid"
...
not valid
>>>
Instálelo con pip ( pip install validators
).
EDITAR Como señala @Kwame, el código valida la url incluso si teh .com, .co no están presentes.
Esto es simple y funciona:
Así que min_attr
tiene la cadena básica que debe estar presente para definir la URL, es decir, http://
parte y parte de google.com
.
urlparse.scheme
almacena http://
y
urlparse.netloc
almacena el nombre de dominio google.com
all()
devuelve verdadero si todas las variables dentro devuelven verdadero. Entonces, si result.scheme
y result.netloc
está presente, la URL es válida y, por lo tanto, devuelve True
.
from urlparse import urlparse
def url_check(url):
min_attr = (''scheme'' , ''netloc'')
try:
result = urlparse(url)
if all([result.scheme, result.netloc]):
return True
else:
return False
except:
return False
note - lepl ya no es compatible, lo siento (puede usarlo, y creo que el código siguiente funciona, pero no va a recibir actualizaciones).
rfc 3696 http://www.faqs.org/rfcs/rfc3696.html define cómo hacerlo (para http urls y correo electrónico). Implementé sus recomendaciones en python usando lepl (una biblioteca de analizador). ver http://acooke.org/lepl/rfc3696.html
usar:
> easy_install lepl
...
> python
...
>>> from lepl.apps.rfc3696 import HttpUrl
>>> validator = HttpUrl()
>>> validator(''google'')
False
>>> validator(''http://google'')
False
>>> validator(''http://google.com'')
True