如何在Python中使用email-validator验证电子邮件地址

1,196 阅读10分钟

简介

无论你是为你的网站创建一个注册表格,还是你只需要从你的邮件列表中删除所有无效的电子邮件地址,你都不能不执行以下过程 电子邮件验证.

你需要验证一个电子邮件地址是否真实,检查它是否符合要求的形式,并能接收电子邮件。这必须有效和安全地进行。

这就是email-validator 的作用。它是一个易于使用,但又强大的Python库,用于验证电子邮件地址。

在本指南中,我们将介绍这个库的基本知识,发现什么时候和为什么可以使用它,以及什么时候不能使用。我们将通过实际的例子来阐述这些内容,帮助你了解如何使用email-validator

什么是email-validator

正如我们之前所说,email-validator 是一个强大的Python库,用于验证电子邮件地址。它执行两种类型的验证 -语法验证交付能力验证。这一点很重要,因为电子邮件地址必须满足所需的形式,同时有一个可解析的域名,才能被视为有效。

语法验证确保电子邮件地址的字符串表示形式为 ,如example@stackabuse.com
可送达性验证确保语法正确的电子邮件地址具有可解析的域名(@ 符号后的字符串 -stackabuse.com

简单地说,它确保经过验证的电子邮件地址能够发送和接收电子邮件信息。

在此基础上,email-validator 对我们有一个小小的奖励,如果电子邮件地址是有效的,email-validator 可以返回其规范化的形式,这样我们就可以以适当的方式将其存储在数据库中。另一方面,如果电子邮件地址是无效的,email-validator 会给我们一个清晰的、人类可读的错误信息,帮助我们理解为什么传递的电子邮件地址是无效的。

在其最简单的形式中,电子邮件地址的规范化意味着小写电子邮件地址的域名(@ 符号之后的序列),因为它是不分大小写的。

在更复杂的规范化案例中,域名部分包括一些Unicode字符,规范化包括Unicode和ASCII字符之间的各种转换。问题在于不同的Unicode字符串对终端用户来说可能看起来和意思是一样的,所以规范化应该确保这些字符串将以同样的方式被记录下来,因为它们实际上代表了同一个领域。

值得一提的是,这个库并不是为不符合example@domainname.com 的形式的电子邮件地址而设计的。

例如,它不会正确验证电子邮件中的To: 行(例如:To: Example Name <example@domainname.com> )。

email-validator与RegEx的邮件验证对比

我们通常使用某种 ***正则表达式(RegEx)***来验证电子邮件地址的正确形式,如果你只需要确保一些电子邮件地址符合要求的形式,那么它是一个很好的选择。它是一种众所周知的技术,易于编写和维护,而且执行起来不需要消耗太多的计算能力。

另一方面,电子邮件地址的验证有时会复杂得多。一个包含电子邮件地址的字符串可能符合电子邮件地址的指定形式,但仍然不能被认为是一个正确的电子邮件地址,因为域名没有解析。

例如,example@ssstackabuse.com 符合电子邮件地址的指定形式,但不是有效的,因为域名(ssstackabuse.com)不存在,因此不能解析,该例子的电子邮件地址不能发送和接收电子邮件。

另一方面,example@stackabuse.com ,符合有效电子邮件地址的两个要求。它符合所需的形式,并且域名可以解析。因此,它可以被认为是一个有效的电子邮件地址。

在这种情况下,email-validator 提供了一个优越的解决方案--它通过一个简单的函数调用来执行语法和可传递性验证,因此不需要费力地确保电子邮件地址能够真正发送和接收电子邮件。如果只用正则表达式来编写这两种验证的代码,那是不可能的。

注意:事实上,如果不发送电子邮件并观察结果,就不可能保证电子邮件是否会被收到。然而,你可以检查它是否收到电子邮件,这是一种绝对的可能性。

这两点使我们有充分的理由支持email-validator ,而不是正则表达式。它更容易使用,而且仍然可以更有效地执行更多的任务。

如何安装email-validator

email-validator 库在PyPI上是可用的,所以通过pippip3 的安装是非常直接的。

$ pip install email-validator
$ pip3 install email-validator

现在你有了email-validator ,可以在Python脚本中使用。

email-validator验证电子邮件地址?

email-validator 库的核心是它的validate_email() 方法。它接受一个电子邮件地址的字符串作为参数,并对该地址进行验证。如果传递的电子邮件地址是有效的validate_email() 方法将返回一个包含所传递的电子邮件地址的规范化形式的对象,但如果是无效的电子邮件地址,它将引发EmailNotValidError ,并提供一个清晰的、人类可读的错误信息,帮助我们理解为什么传递的电子邮件地址是无效的。

EmailNotValidError 实际上只是一个抽象的类,用于检测验证过程中发生的错误,因此,它不用于表示和描述实际的错误。

为此,EmailNotValidError 类有两个子类,描述实际发生的错误。第一个是EmailSynaxError ,当语法验证失败时,它就会被提出来,这意味着传递的电子邮件不符合电子邮件地址的要求形式。第二个是EmailUndeliverableError ,当传递性验证失败时,意味着传递的电子邮件地址的域名不存在。

现在我们终于可以看看如何使用validate_email() 方法了。当然,第一步是把它导入我们的脚本,然后我们就可以使用它了。

from email_validator import validate_email

testEmail = "example@stackabuse.com"

emailObject = validate_email(testEmail)
print(emailObject.email)

由于传递的testEmail 是一个有效的电子邮件地址,前面的代码将输出存储在testEmail 变量中的电子邮件地址的规范化形式。

example@stackabuse.com

**注意:**在前面的例子中,输出的结果与testEmail 中的原始地址是一样的,因为它本来就是规范化的。如果你把未规范化的电子邮件形式传递给validate_email() 方法,返回的电子邮件地址将被规范化,正如预期。

如果我们把原来的testEmail 改为"example@STACKabuse.com" ,前面的代码仍然会有相同的输出,因为它是规范化的。

example@stackabuse.com

另一方面,如果我们将无效的电子邮件地址传递给validate_email() 方法,前面的代码将提示我们相应的错误信息。下面的例子中,testEmail 将通过语法验证,但由于域名ssstackabuse.com 不存在,所以无法通过交付性验证。

testEmail = "example@ssstackabuse.com"

在这种情况下,前面的代码会在其中提示一个长的错误,即。

>> ...
>> raise EmailUndeliverableError("The domain name %s does not exist." % domain_i18n)
email_validator.EmailUndeliverableError: The domain name ssstackabuse.com does not exist.

根据这个提示,我们可以得出结论,通过的邮件是无效的,因为它的域名不存在。在语法无效的情况下,也会提示相应的信息,这样我们就可以很容易地得出结论,传递的电子邮件地址不符合电子邮件地址的要求形式。

你也可以从中自动提取一个更方便用户和人类阅读的错误信息。为了从前面的提示中只提取错误信息,我们需要将前面的代码重写如下。

from email_validator import validate_email, EmailNotValidError

testEmail = "examplestackabuse.com"

try:
    # Validating the `testEmail`
    emailObject = validate_email(testEmail)

    # If the `testEmail` is valid
    # it is updated with its normalized form
    testEmail = emailObject.email
    print(testEmail)
except EmailNotValidError as errorMsg:
    # If `testEmail` is not valid
    # we print a human readable error message
    print(str(errorMsg))

这段代码将只输出一个从前面的提示中提取的简单错误信息。

The domain name ssstackabuse.com does not exist.

**注意:**我们已经利用了EmailNotValidError 类的优势。我们已经尝试在try 块中执行电子邮件验证,并确保在验证失败的情况下在except 块中捕获错误。 没有必要单独捕获EmailSyntaxErrorEmailUndeliverableError ,因为它们都是被捕获的EmailNotValidError 类的子类,而且错误的类型可以很容易地通过打印的错误信息来确定。

validate_email()- 可选参数

默认情况下,validate_email() 方法只接受一个参数--需要验证的电子邮件地址的字符串表示,但可以接受其他一些关键字参数。

  • allow_smtputf8- 默认值是True ,如果设置为Falsevalidate_email() 不会验证国际化的电子邮件地址,只是验证那些域名只由ASCII字符组成的地址(在这种情况下,域名中不允许有UTF-8字符)。
  • Check_deliverability- 默认值是True ,如果设置为False ,则不进行递送性验证。
  • 允许空的地方- 默认值是False ,如果设置为True ,将允许电子邮件地址的空本地部分(即:@stackabuse.com 将被视为有效的电子邮件地址)。

ValidatedEmail对象

你可能已经注意到,我们一直在通过emailObject.email 来访问一个电子邮件地址的规范化形式。这是因为当一个有效的电子邮件地址作为参数被传递时,validate_email() 方法返回ValidatedEmail 对象(在以前的例子中,它被存储在emailObject 变量中)。

ValidatedEmail 对象包含多个属性,描述了规范化电子邮件地址的不同部分。email 属性包含了经过验证的电子邮件地址的规范化形式,因此,我们需要使用. 符号访问它 -emailObject.email

一般来说,我们可以通过使用variableName.attributeName (其中variableName 是用于存储ValidatedEmail 对象的变量)访问ValidatedEmail 对象的任何属性。

例如,假设我们已经用validate_email() 方法验证了example@sTaCkABUSE.cOm 。产生的ValidatedEmail 对象将包含一些有趣和有用的属性,如下表所述。

属性名称示例值说明
电子邮件example@stackabuse.com电子邮件地址的规范化形式。
ascii_emailexample@stackabuse.com只有ASCII形式的email 属性。如果local_part 包含任何种类的国际化字符,这个属性将被设置为None
本地_部分例子@ 符号前的字符串,是电子邮件地址的规范化形式。
ascii_local_part例子如果没有国际化的字符,这个属性被设置为ASCII唯一形式的local_part 属性。否则,它被设置为None
域名stackabuse.com@ 符号后的字符串,是电子邮件地址的正常化形式。如果它包含非ASCII字符,smptutf8 属性必须是True
ascii_domainstackabuse.comdomain 属性的唯一ASCII形式。
smtputf8一个布尔值。如果allow_smtputf8=False 参数被传递给validate_email() 方法,这个参数就是False ,否则就是True

注意:所述属性的ASCII变体是使用Punycode编码语法生成的。它是一种编码语法,用于将Unicode字符串转换为ASCII字符串,以便在应用程序中使用国际化域名(IDNA)。

结论

总而言之,email-validator 是一个在 Python 中验证电子邮件地址的伟大工具。

在本指南中,我们已经涵盖了使用这个库的所有重要方面,使你对它有一个全面的认识。你应该能够理解何时和如何使用email-validator ,以及何时选择一些替代工具。