python发送多人邮件没有展示收件人问题的解决方法4 E7 r% s: Q9 U$ H
这篇文章主要为大家详细介绍了python发送多人邮件没有展示收件人问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下: T2 O+ \) g7 u4 S7 e
背景:- d0 S- C4 v. {
5 F9 \. C; g2 K2 b9 Q工作过程中需要对现有的机器、服务做监控,当服务出现问题后,邮件通知对应的人 # o t/ m/ A$ w, E , s) H) d6 \) ~* X9 q- w, F/ }( ]& r问题: 8 n$ Q( n4 S* p) _) r ! V, c3 o V P- B% b使用python 2.7自带的email库来进行邮件的发送,但是发送后没有展示收件人列表内容 $ i9 R1 N) ~' ^7 V: m: Q; x6 g* U. z9 A- v2 b
问题代码示例:, ^0 ?, z7 I+ }. e0 u- x
# -*- coding:utf-8 -*-+ j% K. h4 F, `- ?; g. ~/ e8 F
import smtplib 9 l( n; Y8 n1 h9 Ufrom email.mime.multipart import MIMEMultipart) _- t }; D& t- }; n
from email.mime.text import MIMEText" n: g2 u+ c& X' D* X2 |) y& y$ ^
E; b) Q. D9 E( X/ m/ o
def send_email_to(fromAdd, toAdd, subject, html_text, filename): 5 |) d$ Y) Q1 f3 @9 C7 J! M server = 'mail.****.com'% l9 [: }% \3 O' r1 x
user = '*****'+ e* C5 v. D. y2 S x, u, K
password = '********'* v( g9 f! z7 B/ }
: f4 V; e1 Y& ], Z4 W) f* ^3 G
strFrom = fromAdd % C/ o+ a- |. q8 T4 b e strTo = toAdd+ j3 W" L* ]/ M0 B/ {7 m
1 w5 L' I, l- M: P4 C8 y* E3 a: T q6 _ msgRoot = MIMEMultipart('related')( b' E4 M4 f1 U
msgRoot['Subject'] = subject2 g9 w) e( r2 @9 S* g' H/ X
msgRoot.preamble = 'This is a multi-part message in MIME format.'& {1 o a$ p7 w! [6 t
; n# Y: @ k2 @ K" d# V/ d$ Q4 A) j msgAlternative = MIMEMultipart('alternative')! ?: W. n* X6 q e; r6 h
msgRoot.attach(msgAlternative)" N, p; o3 }, `8 _, C. `/ g
7 n4 T+ j( \1 w( a4 u msgText = MIMEText(html_text, 'html', 'utf-8') ! h6 p% q3 ]& N H4 g2 j5 L msgAlternative.attach(msgText) 0 m$ y. X, j/ F2 {( F ; [6 [3 J2 V, C smtp = smtplib.SMTP()) f9 [/ R+ i0 f' q
smtp.connect(server) 0 \; \) p1 n0 z, v4 }: T- u6 s) m smtp.login(user, passwd)$ R! w1 Z! m8 ?' C4 g/ p5 B* s
* z1 D8 F. r! }" u1 B
att5 = MIMEText(open(filename, 'rb').read(), 'base64', 'utf-8') v) K1 K2 _) z2 u( y: s att5["Content-Type"] = 'application/octet-stream'4 E* Y) s% i, K5 |- F5 y- b
att5["Content-Disposition"] = 'attachment; filename="fail_7_storage.txt"' 0 R8 U8 G. H1 ], n# K msgRoot.attach(att5)# E% I! ?, t3 W6 n2 h; B
8 `+ k# F' T/ Y8 L4 r; |8 D7 \, ]/ N
smtp.sendmail(strFrom, strTo, msgRoot.as_string()) J' X* _* k1 R& c" B
smtp.quit()* b$ w/ p$ U' W! {' H# P% l/ b3 F3 V
return 0 U& I: P" S9 `0 ^+ y/ u! `+ ^+ e; l5 J4 N) M# M
6 Z$ m! m2 \9 U9 m2 O
成功代码: 2 j" h. h, b6 ]5 R& \#!/usr/bin/env python1 W; R, p6 @8 \4 R/ W8 @
# -*- coding: utf-8 -*-# @- i- X% F+ K& E. {3 d" S7 F y
8 @, s& G( J$ ?. o% f7 L
import smtplib, D( K, o- ?& V
from email.mime.multipart import MIMEMultipart ; C. G/ I& l1 s5 G1 ufrom email.mime.text import MIMEText3 Y' p# j9 X. B; H' {0 m# O0 o
from email.utils import parseaddr0 \5 ]/ l5 \3 e$ B$ D, t# J: _
from email.utils import formataddr * ^/ K( D1 j* U$ A: T* rfrom email.header import Header 0 ]7 U( g, z; ]0 G. b0 q4 p- y4 j) A# n4 T* q# H
: i* N- y) w5 k. G
def __format_addr__(addr):; _4 {% k+ Y& q! l% d- ?4 [/ n/ o
# 解析邮件地址,以保证邮有别名可以显示 2 s- J: D, O, {( T0 c alias_name, addr = parseaddr(addr) ) E: ], [: V: D/ n # 防止中文问题,进行转码处理,并格式化为str返回 ^" T4 @" i% T* B: z) z return formataddr((Header(alias_name,charset="utf-8").encode(), # z- {! G- T1 K# c addr.encode("uft-8") if isinstance(addr, unicode) else addr))/ z+ J0 z' a4 F' a; _/ H a1 Y
* D' g1 u) j& R$ n) N ( V" Z9 L. f9 D( C. cdef send_email_to(fromAdd, toAdd, subject, html_text, filename=None): $ x. D! }! L# h7 m) y+ ?6 t' c' p 0 _; Y5 d* M+ @0 l$ z6 F SERVER = 'mail.***.com'6 W, s: F# M+ T! S* J% p. F
USER = '******' 1 p( h4 a z* J- x. v) I) D PASSWD = '***'0 [* U/ {# ^# h8 M4 {) O4 `
7 R3 j% c( ^( v strFrom = __format_addr(fromAdd)1 ]* n) `, U7 b0 w% x. G4 \, |: @
, w- y" f% E$ w0 I* \$ ~% l' {5 N
strTo = list()- F7 |. f6 e0 q% R8 s
# 原来是一个纯邮箱的list,现在如果是一个["jayzhen<jayzhen@jz.com>"]的list给他格式化. D( q6 t |6 L& @ O
try:: r. f: f7 V6 B) }( z
for a in toAdd:0 ]% y( m5 p& e+ K6 T' o
strTo.append(__format_addr(a))# A# m; Y" e5 t: k
except Exception as e: $ y4 X$ \5 B/ _% L # 没有对a和toadd进行type判断,出错就直接还原/ B3 J* V' m' I: y1 V3 x0 [
strTo = toAdd& E% B4 F( ]9 H" O7 \
M! y8 i/ F; K& l2 d6 @+ [
msgRoot = MIMEMultipart('related'), S! H4 N9 i/ ^- P! S
msgRoot.preamble = 'This is a multi-part message in MIME format.'6 O* `! j1 n4 c5 L
$ b% N# D) E- `9 t" ?0 B/ |$ I: d msgAlternative = MIMEMultipart('alternative')2 V6 Y8 i& ~- m. c$ Z; F
msgRoot.attach(msgAlternative)" e! |) `8 d. W+ Z% I
' h6 S! S% v5 d) }: u% q # 邮件对象 : r8 ?* d L; J3 u msgText = MIMEText(html_text, 'html', 'utf-8') 0 ~7 r$ ?2 H0 _8 q msgRoot['Subject'] = Header(subject) # 这是邮件的主题,通过Header来标准化2 |$ c" S* d, A" K- h
msgRoot['From'] = strFrom # 发件人也是被格式化过的 + o: R+ K2 H, P$ ?: O msgRoot['to'] = ','.join(strTo) # 这个一定要是一个str,不然会报错“AttributeError: 'list' object has no attribute 'lstrip'” 8 `3 I5 l* p) z" u/ Z& R msgAlternative.attach(msgText) 5 a/ P7 [5 m7 t9 @- Y3 J! ]5 M; n& j% V2 Y: B8 F
smtp = smtplib.SMTP(SERVER, 11) % X `! J/ I* s) u# c smtp.set_debuglevel(0) , @* ]) H$ }) I3 d4 G- t # smtp.connect(SERVER)2 F& w* R2 p9 n4 x$ V# O
smtp.login(USER, PASSWD)* e9 z) `* n$ A, t" F, Z, @: Y+ G. \
# 这里要注意了,这里的fromadd和toAdd和msgRoot['From'] msgRoot['to']的区别 4 Z( k' W) @4 I, _1 k6 r: n smtp.sendmail(fromAdd, toAdd, msgRoot.as_string()) 9 _8 W9 i4 }, x smtp.quit(): M) A- O( c. ]/ Q
总结:8 S" ~- d$ q5 q: ]" L
8 m' t* |9 j7 q( b看到 msgRoot[‘to’] = ‘,’.join(strTo) 与 msgRoot[‘to’] = strTo% Y9 a5 S5 f" z7 [: C
" g% j( J* R+ T' L3 o6 U
实验过程中发现这个[“to”]一定要是一个str,不然会报错“AttributeError: ‘list’ object has no attribute ‘lstrip’” & ~6 `. g% u2 N, ~$ A& o/ }% k, j+ [: J/ z# z+ |
同时也发现[“to”]的数据类型与sendmail(from_addrs,to_addrs,…)的to_addrs不同;前者为str类型,多个地址使用逗号分隔,后者为list类型* g" \$ R/ }& L3 W