187 votes

Comment valider une url en Python ? (Malformé ou non)

J'ai url de l'utilisateur et je dois répondre avec le HTML récupéré.

Comment puis-je vérifier si l'URL est malformée ou non ?

Par exemple :

url='google'  // Malformed
url='google.com'  // Malformed
url='http://google.com'  // Valid
url='http://google'   // Malformed

2 votes

2 votes

Essayez simplement de le lire, si par exemple httplib lève une exception, alors vous saurez qu'il n'est pas valide. Les urls bien formées ne sont pas toutes valides ¡!

1 votes

198voto

Jabba Points 1664

Utilisez le validateurs paquet :

>>> 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
>>>

Installez-le à partir de PyPI avec pip ( pip install validators ).

5 votes

Il y aura une erreur pour les urls de fichiers. Comme "file:///users/file.txt"

2 votes

Échecs pour les urls de localhost validators.url("http://localhost:8080") ValidationFailure(func=url, args={'public': False, 'value': 'http://localhost:8080'})

1 votes

Valable pour http://www.google , http://google.www il s'agit simplement de vérifier si http:// y a dot (.) between two words

140voto

EEVIAC Points 928

En fait, je pense que c'est le meilleur moyen.

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 vous définissez verify_exists a True il vérifiera effectivement que l'URL existe, sinon il se contentera de vérifier si elle est formée correctement.

edit : ah oui, cette question est un duplicata de celle-ci : Comment vérifier si une URL existe avec les validateurs de Django ?

59 votes

Mais cela ne fonctionnera que dans l'environnement django, pas autrement.

0 votes

Oh désolé, je ne sais pas pourquoi j'ai pensé que cette question avait le tag django. Oups, désolé.

26 votes

verify_exists est déprécié. -1

126voto

cetver Points 3152

Regex de validation d'url de django ( source ) :

import re
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

2 votes

Une curiosité... avez-vous ajouté l'élément ftp ? Ou ai-je une ancienne version de django ?

0 votes

>>wiso : django version 1.3 ( vérifiez vous-même : /django/core/validators.py, line:47 ) someftp.com - url invalide ? Même l'analyseur stackoferlow someftp.com fait office de lien).

0 votes

>>Yugal Jindle : les développeurs de django pensent que le protocole est nécessaire, mais vous pouvez modifier cette regexp si vous ne le pensez pas

113voto

alemol Points 81

Une version Vrai ou Faux, basée sur la réponse de @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'
e = 'https://stackoverflow.com'

def uri_validator(x):
    try:
        result = urlparse(x)
        return all([result.scheme, result.netloc])
    except:
        return False

print(uri_validator(a))
print(uri_validator(b))
print(uri_validator(c))
print(uri_validator(d))
print(uri_validator(e))

Donne :

True
False
False
False
True

11 votes

Je ne savais pas qu'on pouvait tester une instruction if avec une liste d'éléments non nuls. C'est très utile. Aussi +1 pour l'utilisation d'un module intégré

0 votes

Les listes vides correspondent à Faux dans les contextes de condition.

16 votes

Cela permet tout. Il rend True pour la chaîne fake ou même pour une chaîne vide. Il n'y aura jamais d'erreur parce que ces attributs sont toujours présents, et la liste aura toujours une valeur booléenne de True parce qu'elle contient ces attributs. Même si tous les attributs sont nuls, la liste sera toujours non vide. Vous avez besoin d'une validation des attributs parce que tout passe comme vous le faites maintenant.

34voto

jonaprieto Points 725

Aujourd'hui, j'utilise ce qui suit, sur la base de la réponse du Padam :

$ python --version
Python 3.6.5

Et voilà à quoi ça ressemble :

from urllib.parse import urlparse

def is_url(url):
  try:
    result = urlparse(url)
    return all([result.scheme, result.netloc])
  except ValueError:
    return False

Il suffit d'utiliser is_url("http://www.asdf.com") .

J'espère que cela vous aidera !

0 votes

Il échoue dans le cas où le nom de domaine commence par un tiret, ce qui n'est pas valide. tools.ietf.org/html/rfc952

4 votes

Ceci n'est utile que pour diviser les composants dans le cas particulier où l'URI est connu de l'utilisateur. PAS être malformé. Comme je l'ai répondu précédemment à l'autre réponse similaire, cela valide les URI malformés, tels que https://https://https://www.foo.bar .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X