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的地址格式,本文就介紹這么多啦。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM