Python邮件

发送纯文本邮件(此案例发送接收成功)

 1 import smtplib
 2 from email.mime.text import MIMEText
 3 
 4 '''
 5 MIMEText三个主要参数
 6 1.邮件内容
 7 2.MIME子类型,此案例用plain表示text类型
 8 3.邮件编码格式
 9 '''
10 msg = MIMEText('这是邮件内容', 'plain', 'utf-8')
11 from_addr = '18555251650@qq.com'
12 pwd = 'dlgrhegpprgdcbbf' #这个不是密码,是腾讯邮箱授权码,类似密码
13 to = '18555251650@qq.com'
14 smtp_srv = 'smtp.qq.com'
15 
16 try:
17     srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
18     srv.login(from_addr, pwd)
19     srv.sendmail(from_addr, [to], msg.as_string()) #[to]也可以用to,字符串也可以,详见API代码注释
20     srv.quit()
21 except Exception as e:
22     print(e)

 发送HTML格式邮件(此案例发送接收成功,邮件正文带表格)

 1 import smtplib
 2 from email.mime.text import MIMEText
 3 
 4 mail_content = '''
 5 <!DOCTYPE html>
 6 <html lang="en">
 7     <head>
 8         <meta charset="UTF-8">
 9         <title>这是标题</title>
10     </head>
11     <body>
12         <h1>这是一封HTML格式邮件</h1>
13         <table border=2>
14             <tr><td>第一行第一列</td><td>第一行第二列</td></tr>
15             <tr><td>第二行第一列</td><td>第二行第二列</td></tr>
16         </table>
17     </body>
18 </html>
19 '''
20 
21 msg = MIMEText(mail_content, 'html', 'utf-8')
22 from_addr = '18555251650@qq.com'
23 pwd = 'dlgrhegpprgdcbbf'
24 to = ['18555251650@qq.com']
25 smtp_srv = 'smtp.qq.com'
26 try:
27     srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
28     srv.login(from_addr, pwd)
29     srv.sendmail(from_addr, to, msg.as_string())
30 except Exception as e:
31     print(e)

 发送带附件的邮件(此案例发送接收成功)

 1 import smtplib
 2 from email.mime.text import MIMEText  # 构建附件使用
 3 from email.mime.multipart import MIMEMultipart  # 构建基础邮件使用
 4 
 5 mail_mul = MIMEMultipart()
 6 # 构建邮件正文
 7 mail_text = MIMEText('这是邮件正文', 'plain', 'utf-8')
 8 # 把构建好的邮件正文附件加邮件中
 9 mail_mul.attach(mail_text)
10 
11 with open('附件.jpg', 'rb') as f:
12     s = f.read()
13     # 设置附件的MIME和文件名
14     m = MIMEText(s, 'base64', 'utf-8')
15     m['Content-Type'] = 'application/octet-stream'
16     m['Content-Disposition'] = 'attachment;filename="abc.jpg"'  # 附件名若为中文收到的邮件附件名会有问题
17     mail_mul.attach(m)
18 
19 from_addr = '18555251650@qq.com'
20 pwd = 'dlgrhegpprgdcbbf'
21 to = ['18555251650@qq.com']
22 smtp_srv = 'smtp.qq.com'
23 
24 try:
25     srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
26     srv.login(from_addr, pwd)
27     srv.sendmail(from_addr, to, mail_mul.as_string())
28     srv.quit()
29 except Exception as e:
30     print(e)

 发送邮件带From, To, Subject,即发送者,接收者,标题(此案例发送接收成功)

 1 import smtplib
 2 from email.mime.text import MIMEText
 3 from email.header import Header
 4 
 5 msg = MIMEText('这是邮件正文', 'plain', 'utf-8')
 6 
 7 msg['From'] = Header('从这里发出去的', 'utf-8')
 8 msg['To'] = Header('发到这个地方去', 'utf-8')
 9 msg['Subject'] = Header('这个是标题', 'utf-8')
10 
11 from_addr = '18555251650@qq.com'
12 pwd = 'dlgrhegpprgdcbbf'
13 to = ['18555251650@qq.com']
14 
15 smtp_srv = 'smtp.qq.com'
16 
17 try:
18     srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
19     srv.login(from_addr, pwd)
20     srv.sendmail(from_addr, to, msg.as_string())
21     srv.quit()
22 except Exception as e:
23     print(e)

 发送同时带纯文件和HTML内容的邮件(此案例发送接收成功)

 1 import smtplib
 2 from email.mime.text import MIMEText
 3 from email.mime.multipart import MIMEMultipart
 4 
 5 msg = MIMEMultipart('alternative')
 6 
 7 html_content = '''
 8 <!DOCTYPE html>
 9 <html lang="en">
10     <head>
11         <meta charset="UTF-8">
12         <title>这是标题</title>
13     </head>
14     <body>
15         <h1>这是一封HTML格式邮件</h1>
16         <table border=2>
17             <tr><td>第一行第一列</td><td>第一行第二列</td></tr>
18             <tr><td>第二行第一列</td><td>第二行第二列</td></tr>
19         </table>
20     </body>
21 </html>
22 '''
23 
24 msg_html = MIMEText(html_content, 'html', 'utf-8')
25 msg.attach(msg_html)
26 msg_text = MIMEText('这是纯文本邮件正文', 'plain', 'utf-8')  # 收到的邮件中看不到这个内容
27 msg.attach(msg_text)
28 
29 from_addr = '18555251650@qq.com'
30 pwd = 'dlgrhegpprgdcbbf'
31 to = ['18555251650@qq.com']
32 
33 smtp_srv = 'smtp.qq.com'
34 
35 try:
36     # server = smtplib.SMTP_SSL(smtp_srv.encode(), 465)  # 加密传输
37     server = smtplib.SMTP(smtp_srv.encode(), 25)  # qq邮箱要求使用TLS加密传输
38     server.starttls()
39     # server.set_debuglevel(1)  # 设置调试级别
40     server.login(from_addr, pwd)
41     server.sendmail(from_addr, to, msg.as_string())
42     server.quit()
43 except Exception as e:
44     print(e)

 接收邮件(此案例接收解析查看邮件成功)

  1 import poplib  # 负责从MDA到MUA下载
  2 # 以下包负责相关邮件结构解析
  3 from email.parser import Parser
  4 from email.header import decode_header
  5 from email.utils import parseaddr
  6 
  7 
  8 # 得到邮件的原始内容,这个过程主要负责从MDA到MUA的下载并使用Parse粗略解析
  9 def getMsg():
 10     email = '18555251650@qq.com'
 11     pwd = 'dlgrhegpprgdcbbf'
 12     pop3_srv = 'pop.qq.com'  # 端口995
 13     srv = poplib.POP3_SSL(pop3_srv)  # SSL代表是安全通道
 14     srv.user(email)  # user代表email地址
 15     srv.pass_(pwd)  # pass_代表密码
 16 
 17     # 以下操作根据具体业务具体使用
 18     # stat返回邮件数量和占用空间
 19     # 注意stat返回一个tuple格式
 20     msgs, counts = srv.stat()
 21     print('msgs=', msgs)
 22     print('counts=', counts)
 23 
 24     # list返回所有邮件编号列表
 25     # mails是所有邮件编号列表
 26     rsp, mails, octets = srv.list()
 27     # 可以查看返回的mails列表类似 [b'1 3946', b'2 2309', b'3 29794', ……]
 28     print('mails=', mails)
 29 
 30     # 获取最新一封邮件,注意,邮件索引号是从1开始,最新代表索引最高
 31     index = len(mails)
 32     # retr负责返回一个具体索引号的一封信的内容,此内容不具有可读性
 33     # lines存储邮件的最原始文本的每一行
 34     rsp, lines, octets = srv.retr(index)
 35 
 36     # 获得整个邮件的原始文本
 37     msg_count = b'\r\n'.join(lines).decode('utf-8')
 38     # 解析出邮件整个结构体
 39     # 参数是解码后的邮件整个
 40     msg = Parser().parsestr(msg_count)
 41 
 42     srv.quit()  # 关闭链接
 43     return msg
 44 
 45 
 46 # 详细解析得到的邮件内容
 47 # msg代表是邮件的原始内容
 48 # ident代表的是邮件嵌套的层级
 49 def parseMsg(msg, indent=0):
 50     '''
 51     1.邮件完全可能是有嵌套格式
 52     2.邮件只有一个From, To,Subject之类的信息
 53     3.indent:描述邮件里面有几个邮件MIMEXXX类型的内容,展示的时候进行相应缩进
 54     '''
 55     # 想办法提取出头部信息
 56     # 只有在第一层的邮件中才会有相关内容
 57     # 此内容只有一个
 58     if indent == 0:
 59         for header in ['From', 'To', 'Subject']:
 60             # 使用get可以避免如果没有相关关键字报错的可能性
 61             # 如果没有关键字‘From’,我们使用msg['From']会报错
 62             value = msg.get(header, '')
 63             if value:
 64                 # Subject中的内容直接解码就可以,他是字符串类型
 65                 if header == 'Subject':
 66                     value = decodeStr(value)
 67                 # 如果是From和To字段,则内容大概是‘我的邮箱<xxx@qq.com>’这种格式
 68                 else:
 69                     hdr, addr = parseaddr(value)
 70                     name = decodeStr(hdr)
 71                     # 最终返回形如‘我的邮箱<xxx@qq.com>’的格式
 72                     value = '{}<{}'.format(name, addr)
 73             print('indent=', indent, 'header=', header, 'value=', value)
 74 
 75     # 下面代码关注邮件内容本身
 76     # 邮件内容中,有可能是multipart类型,也有可能是普通邮件类型
 77     # 下面的解析使用递归方式
 78     if (msg.is_multipart()):
 79         # 如果是multipart类型,则调用递归解析
 80         # 得到多部分邮件的一个基础邮件部分
 81         parts = msg.get_payload()
 82         # enumerate函数是内置函数
 83         # 作用是将一个列表,此处是parts,生成一个有索引和parts原内容构成的新的列表
 84         # 例如enumerate(['a','b','c'])结果是:[(1,'a'),(2,'b'),(3,'c')]
 85         for n, part, in enumerate(parts):
 86             print('{}spart:{}'.format(' ' * indent, n))
 87             parseMsg(part, indent + 1)
 88     else:  # 基础类型
 89         # get_content_type是系统提供函数,得到内容类型
 90         content_type = msg.get_content_type()
 91         if content_type == 'text/plain' or content_type == 'text/html':
 92             content = msg.get_payload(decode=True)
 93             charset = guessCharset(msg)
 94             if charset:
 95                 content = content.decode(charset)
 96             print('{}Text:{}'.format(indent, content))
 97         else:  # 不是文本内容,则应该是附件
 98             print('{}Attachment:{}'.format(indent, content_type))
 99 
100 
101 def decodeStr(s):
102     '''
103     s代表一封邮件中From,To,Subject中的任一项
104     对s进行解码,解码是编码的逆过程
105     '''
106     value, charset = decode_header(s)[0]
107     # cahrset完全可能为空
108     if charset:
109         # 如果指定编码,则用指定编码格式进行解码
110         value = value.decode(charset)
111     return value
112 
113 
114 def guessCharset(msg):
115     charset = msg.get_charset()
116     if charset is None:
117         content_type = msg.get('Content-Type', '').lower()
118         pos = content_type.find('charset=')
119         if pos >= 0:
120             charset = content_type[pos + 8:].strip()
121     return charset
122 
123 
124 if __name__ == '__main__':
125     msg = getMsg()  # 得到邮件的原始内容
126     print(msg)
127     parseMsg(msg, 0)  # 精确解析邮件内容

 

posted @ 2020-01-09 18:57  xiongjiawei  阅读(202)  评论(0)    收藏  举报