parseaddr函数和formataddr函数的用法

  参考:https://www.pynote.net/archives/630

  parseaddr函数和formataddr函数,都来自email.utils模块,用来在发送Email的时候,“美化”地址中的姓名部分。本文介绍如何使用这两个函数。

  引入parsesaddr和formataddr

  use_parseaddr_formataddr.py

from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr

  由于下面代码需要使用到Header和MIMEText所以一并引入

  带姓名的email地址

  一般情况下,我们使用Email,地址都是直接写成这样(1):123456@qq.com,纯Email,不带姓名。写成这样没问题,在使用工具或代码(例如MIMEText对象)编写Email内容的时候,地址都可以直接写成这样。

  但是,这个时候,地址还有另外一种写法(2):name<123456@qq.com>,将姓名放在Email地址前面。这种写法增加了姓名,并用尖括号将Email地址括起来,这种写法会让您发出的邮件,看起来更加专业。

  按照第1种写法设置发件人,收到邮件时,地址显示是这样的:

   而如果采用第2种写法,收到邮件时,地址会显示成这样

  首先看发送邮件的写法

   收件人

   这就是带姓名的Email邮件地址格式

  注意:

有的时候,我们使用第1种Email地址发邮件,对方在邮件工具中打开时,还是能看到地址前的姓名,比如QQ信箱。这是因为你的邮件地址在对方的邮件工具里有保存,显示邮件的时候,邮件工具默认将此地址保存的姓名显示了出来。如果对方邮件工具没有保存你的邮件,就不会出现这个现象。

  如何 parsesaddr和formataddr

  parseaddr 函数和 formataddr 函数就是用来合成这种符合Email标准的带姓名的地址格式的。我们继续上一篇的内容,用Python发送Email的技巧,这一篇就是介绍在发送Email的时候,如何使用带姓名的Email地址格式。

from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
# 邮件发件人邮件格式其中pynote.net为发件人用户名可以自定义
# from@qq.com为发件人真实邮箱地址不能自定义
From = 'pynote.net<from@qq.com>'
# 使用parseaddr()方法分隔用户名和邮箱地址
name,addr = parseaddr(From)
print(name,addr)
# pynote.net from@qq.com

# 使用formataddr方法把邮箱用户名和邮箱地址转换成标准Email地址格式
# formataddr方法接收一个元组作为参数,元组的第一个元素是经过Header编码的用户名信息
# 元组的第二个元素是邮箱地址,返回一个str
# 元组的两个元素都可以为空,如果第一个元素为空则返回邮箱地址,如果第二个元素为空则返回用户名经过Header函数编码信息
# 如果两个元素都为空则返回空
fromaddr = formataddr((Header(name,'utf-8').encode(), addr))
print(fromaddr)
# =?utf-8?q?pynote=2Enet?= <from@qq.com>

# 以下为收件者邮箱信息
To = 'mylove<babylove@qq.com>'
name,addr = parseaddr(To)
print(name,addr)
# mylove babylove@qq.com
toaddr = formataddr((Header(name,'utf-8').encode(), addr))
print(toaddr)
# =?utf-8?q?mylove?= <babylove@qq.com>

  注意:使用Header生成的字符串格式,如果name值有asscii字符则格式如下

# asscii字符
name = 'mylove'
print(Header(name,'utf-8').encode())
# =?utf-8?q?mylove?=
print(base64.b64encode(name.encode('utf-8')))
# b'bXlsb3Zl'

  格式解析如下

=?utf-8?q?mylove?=
=? #为固定格式开头
utf-8?#为utf-8编码
q? #只有ascii码不包含中文
mylove #为原文
?= #为固定结尾

  

  如果name包含中文则格式如下

# 包含中文
name = '中文'
print(Header(name,'utf-8').encode())
# =?utf-8?b?5Lit5paH?=
print(base64.b64encode(name.encode('utf-8')))
# b'5Lit5paH'

  如果name包含中文则生成的字符串中包含使用base64解码的字符串,前面使用b?而不是q?

  将带姓名的Email格式作为参数,给parseaddr函数,得到name和addr。name就是姓名,addr就是纯Email,请看parseaddr解析To后的打印显示。然后formataddr函数再将name和addr转换成标准Email地址格式。注意name还要经过Header函数的编码。fromaddr和toaddr,就是最后我们可以使用的地址字符串。我们来使用一下:

# 定义发送邮件的邮件内容信息
msg_str = 'this is a name-based email address test'
# 注意到构造MIMEText对象时
# 第一个参数就是邮件正文
# 第二个参数是MIME的subtype,传入'plain'表示纯文本,最终的MIME就是'text/plain'
# 最后一定要用utf-8编码保证多语言兼容性
msg = MIMEText(msg_str,'plain','utf-8')
msg['From'] = fromaddr
msg['To'] = toaddr
# 把MIMEText对象转换成str
print(msg.as_string())

   msg['From']和msg['To']直接使用formataddr后的字符串,如果有多个这样的字符串地址,用逗号(,)分开。但是sendmail函数不使用编码后的带姓名的Email地址字符串,还是使用纯Email地址,这个细节要注意。带姓名的Email地址的编码,只是改变邮件内容的头部,而不改变投递细节。

  小工具

  这个函数小工具,合并了 parseaddr和formataddr功能,输入 以第2种方式编写的Email地址,得到直接可以在MIMEText中使用字符串,请收藏:

def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name,'utf-8').encode(), addr))

  这个函数即把以第2中方式写入的Email地址,返回为可以在MIMEText中使用字符串

  这个函数还自带了一定能的容错性:

# 容错性
# 标准格式
print(_format_addr('godaddy<1123456@hotmail.com>'))
# =?utf-8?q?godaddy?= <1123456@hotmail.com>
# 没有用户名只有email地址地址没有使用<>括起来
print(_format_addr('1123456@hotmail.com'))
# 1123456@hotmail.com
# 没有用户名
print(_format_addr('<1123456@hotmail.com>'))
# 1123456@hotmail.com
print(_format_addr('pythonisgood<1123456@hotmail.com>'))
# =?utf-8?q?pythonisgood?= <1123456@hotmail.com>
print(_format_addr('pythonisgood'))
# 用户名和地址都为空返回也为空字符串
print(_format_addr(''))
# 

  parseaddr和formataddr函数的使用并不难,关键是要里面Email的地址格式,本文就介绍这么多啦。

  

原文地址:https://www.cnblogs.com/minseo/p/15251857.html