web-dev-qa-db-fra.com

Vérification de la validité des courriels dans Django/Python

J'ai écrit une fonction pour ajouter des emails à la base de newsletter. Jusqu'à ce que j'ajoute la vérification de la validité du courrier envoyé, tout fonctionnait parfaitement. Maintenant, chaque fois, je reçois un "mauvais courriel" en retour. Quelqu'un peut-il voir des erreurs ici? La regex utilisée est:

\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b et il est valide à 100% ( http://gskinner.com/RegExr/ ), mais je l’utilise peut-être mal ou il peut y avoir une erreur de logique:

def newsletter_add(request):
    if request.method == "POST":   
        try:
            e = NewsletterEmails.objects.get(email = request.POST['email'])
            message = _(u"Email is already added.")
            type = "error"
        except NewsletterEmails.DoesNotExist:
            if validateEmail(request.POST['email']):
                try:
                    e = NewsletterEmails(email = request.POST['email'])
                except DoesNotExist:
                    pass
                message = _(u"Email added.")
                type = "success"
                e.save()
            else:
                message = _(u"Wrong email")
                type = "error"

import re

def validateEmail(email):
    if len(email) > 6:
        if re.match('\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b', email) != None:
            return 1
    return 0
61
muntu

UPDATE 2017: le code ci-dessous a 7 ans et a été modifié, corrigé et étendu depuis. Pour ceux qui souhaitent le faire maintenant, le code approprié est utilisé: https://github.com/Django/django/blob/master/Django/core/validators.py#L168-L180

Voici une partie de Django.core.validators que vous pouvez trouver intéressant :)

class EmailValidator(RegexValidator):

    def __call__(self, value):
        try:
            super(EmailValidator, self).__call__(value)
        except ValidationError, e:
            # Trivial case failed. Try for possible IDN domain-part
            if value and u'@' in value:
                parts = value.split(u'@')
                domain_part = parts[-1]
                try:
                    parts[-1] = parts[-1].encode('idna')
                except UnicodeError:
                    raise e
                super(EmailValidator, self).__call__(u'@'.join(parts))
            else:
                raise

email_re = re.compile(
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')

par conséquent, si vous ne souhaitez pas utiliser de formulaires et de champs de formulaire, vous pouvez importer email_re et l'utiliser dans votre fonction, ou même mieux - importez validate_email et utilisez-le, en saisissant la possibilité ValidationError.

def validateEmail( email ):
    from Django.core.validators import validate_email
    from Django.core.exceptions import ValidationError
    try:
        validate_email( email )
        return True
    except ValidationError:
        return False

Et voici Mail :: RFC822 :: Adresse regexp utilisé en Perl, si vous avez vraiment besoin d'être aussi paranoïaque.

141
cji
from Django.core.exceptions import ValidationError
from Django.core.validators import validate_email
try:
    validate_email("[email protected]")
except ValidationError as e:
    print "oops! wrong email"
else:
    print "hooray! email is valid"
113
oblalex

Ick, non, s'il vous plaît, n'essayez pas de valider vous-même les adresses e-mail. C'est une de ces choses que les gens ne font jamais bien.

Votre option la plus sûre, puisque vous utilisez déjà Django, consiste simplement à tirer parti de la validation de son formulaire pour le courrier électronique. Selon les documents ( http://docs.djangoproject.com/en/dev/ref/forms/fields/ ):

>>> from Django import forms
>>> f = forms.EmailField()
>>> f.clean('[email protected]')
u'[email protected]'
>>> f.clean(u'[email protected]')
u'[email protected]'
>>> f.clean('invalid e-mail address')
...
ValidationError: [u'Enter a valid e-mail address.']
47
Nicholas Knight

Vous vous êtes trompé, mais c'est une tâche que vous ne pouvez pas faire de toute façon. Il y a un et un seul moyen de savoir si une adresse RFC 2822 est valide, c'est d'envoyer un courrier et d'obtenir une réponse. Faire autre chose n'améliore même pas un bit le contenu en informations de votre donnée.

Vous vissez également le facteur humain et la propriété d’acceptation, car lorsque vous donnez validateEmail mon adresse de

[email protected]

et vous me dites que j'ai commis une erreur, je dis adieu à votre application.

7
msw

Cette expression régulière validera une adresse email avec une précision raisonnable.

\w[\w\.-]*@\w[\w\.-]+\.\w+

Il autorise les caractères alphanumériques, _, . et -.

1
Zenadix

Je peux voir que beaucoup de réponses ici sont basées sur le framework Django de python. Mais pour vérifier une adresse e-mail, pourquoi installer un logiciel aussi lourd. Nous avons le paquet Validate_email pour Python qui vérifie si un email est valide, correctement formaté et existe réellement. C'est un paquet léger (taille <1MB).

INSTALLATION: 

pip install validate_email

Utilisation de base:

Vérifie si le courrier électronique est au bon format.

from validate_email import validate_email
is_valid = validate_email('[email protected]')

Pour vérifier le domaine mx et vérifier que le courrier électronique existe, vous pouvez installer le package pyDNS avec validate_email.

Vérifier que l'email existe: 

from validate_email import validate_email
is_valid = validate_email('[email protected]',verify=True)

Renvoie True si l'e-mail existe dans le monde réel, sinon False.

0
Himanshu Poddar

Changez votre code à partir de ceci:

re.match ('\ b [\ w .-] + @ [\ w .-] +.\w {2,4}\b', email)

pour ça:

re.match (r '\ b [\ w .-] + @ [\ w .-] +.\w {2,4}\b', email)

fonctionne bien avec moi.

0
Kent Astudillo