本系列博文基于廖雪峰老师的官网Python教程,笔者在大学期间已经阅读过廖老师的Python教程,教程相当不错,官网链接: 廖雪峰官方网站.请需要系统学习Python的小伙伴到廖老师官网学习,笔者的编程环境是Anaconda+Pycharm,Python版本:Python3.
1.电子邮件简介
# 1.邮件经电子邮件软件(MUA)--Mail User Agent(邮件用户代理)发出; # 2.Email从MUA发出,到达MTA--Mail Transfer Agent(邮件传输代理),即Email服务提供商; # 3.Email到达MTA后,MTA把Email投递到邮件的最终目的地MDA--Mail Delivery Agent(邮件投递代理); # 4.Email到达MDA后,存放在某个文件或特殊的数据库里,这个长期保存邮件的地方称为电子邮箱; # 5.邮件的发送接收:发件人-->MUA-->MTA-->MTA-->n个MTA-->MDA<--MUA<--收件人; # 6编写程序来发送和接收邮件,本质是: # a.编写MUA把邮件发到MTA; # b.编写MUA从MDA上收邮件; # 7.发邮件时,MUA和MTA使用的协议:SMTP--Simple Mail Transfer Protocol; # 8.收邮件时,MUA和MDA使用的协议:POP--Post Office Protocol,版本3,称为POP3; # IMAP:Internet Message Access Protocol,版本4,优点:能取邮件,能直接操作MDA上存储的邮件;2.SMTP发送邮件
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
from_addr = input('From: ')
password = input('Password: ') # 注意:该密码不是邮箱登录密码;
to_addr = input('To: ')
smtp_server = input('SMTP server: ')
msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
# 发送HTML邮件
# msg = MIMEText("Test"+"From FUXI...
"+"","html", "utf-8")
msg['From'] = _format_addr('Willard <%s>' % from_addr)
msg['To'] = _format_addr('Admin <%s>' % to_addr)
msg['Subject'] = Header('来自SMTP的问候……', 'utf-8').encode()
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
# 结果输出: From: xxxx@qq.com Password: ngcmrsredduvdccd To: xxxxx@163.com SMTP server: smtp.qq.com ... (221,b'Bye.')
# 发送附件
# 带附件的邮件包含:文本和各个附件本身;构造一个MIMEMultipart对象代表邮件本身,
# 往对象里加MIMEText作为邮件正文,加MIMEbase表示附件;
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEbase
import smtplib
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
from_addr = input('From: ')
password = input('Password: ') # 注意:该密码不是邮箱登录密码;
to_addr = input('To: ')
smtp_server = input('SMTP server: ')
# 邮件对象
msg = MIMEMultipart()
msg['From'] = _format_addr('Willard <%s>' % from_addr)
msg['To'] = _format_addr('Admin <%s>' % to_addr)
msg['Subject'] = Header('Come From SMTP', 'utf-8').encode()
# 邮件正文
msg.attach(MIMEText("Send with Files.", "plain", "utf-8"))
# 添加附件
with open("willard.jpg", "rb") as f:
# a.设置附件的MIME和文件名
mime = MIMEbase("image", "jpg", filename = "willard.jpg")
# b.加上头信息
mime.add_header("Content-Disposition", "attachment", filename = "willard.jpg")
mime.add_header("Content-ID", "<0>")
mime.add_header("X-Attachment-Id", "0")
# c.把附件内容读入
mime.set_payload(f.read())
# d.用base64编码
encoders.encode_base64(mime)
# e.添加到MIMEMultipart
msg.attach(mime)
server = smtplib.SMTP(smtp_server, 25)
server.starttls() # 调用starttls()方法加密
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
# 结果输出: From: xxxx@qq.com Password: ngcmrsredduvdccd To: xxxxx@163.com SMTP server: smtp.qq.com ... (221,b'Bye.')3.POP3收取邮件
# 1.SMTP用于发送邮件,POP3用于收取邮件;
# 2.收取邮件:编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或手机上;
# 3.收取邮件步骤:
# a.用poplib把邮件的原始文本下载到本地;
# b.用email解析原始文本,还原为邮件对象;
# 接收邮件
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import poplib
# a.输入邮件地址,密码和POP3服务器地址
email = input("Email:")
password = input("Password:")
pop3_server = input("POP3 server:")
# b.连接到POP3服务器
server = poplib.POP3(pop3_server)
# c.打开或关闭调试信息
server.set_debuglevel(1)
# d.可选:打印POP3服务器的欢迎文字
print(server.getwelcome().decode("utf-8"))
# e.身份认证
server.user(email)
server.pass_(password)
# f.stat()返回邮件数量和占用空间
print("Message:%s.Size:%s" % server.stat())
# g.list()返回所有邮件的编号
resp, mails, octets = server.list()
print(mails)
# h.获取最新一封邮件
index = len(mails)
resp, lines, octets = server.retr(index)
# i.获取整个邮件的原始文本
msg_content = b"rn".join(lines).decode("utf-8")
msg = Parser().parsestr(msg_content)
# 解析邮件
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
def guess_charset(msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
# indent用于缩进显示:
def print_info(msg, indent=0):
if indent == 0:
for header in ['From', 'To', 'Subject']:
value = msg.get(header, '')
if value:
if header=='Subject':
value = decode_str(value)
else:
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
print('%s%s: %s' % (' ' * indent, header, value))
if (msg.is_multipart()):
parts = msg.get_payload()
for n, part in enumerate(parts):
print('%spart %s' % (' ' * indent, n))
print('%s--------------------' % (' ' * indent))
print_info(part, indent + 1)
else:
content_type = msg.get_content_type()
if content_type=='text/plain' or content_type=='text/html':
content = msg.get_payload(decode=True)
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
print('%sText: %s' % (' ' * indent, content + '...'))
else:
print('%sAttachment: %s' % (' ' * indent, content_type))
if __name__ == "__main__":
print_info(msg, indent = 0)
server.quit()
# 结果输出: Email:xxxx@qq.com Password:ahjycyfdssssedg POP3 server:pop.qq.com +OK XMail POP3 Server v1.0 Service Ready(XMail v1.0) *cmd* 'USER xxx2s4e4@qq.com' *cmd* 'PASS ahjycyfdsssssedg' *cmd* 'STAT' *stat* [b'+OK', b'1', b'8526'] Message:1.Size:8526 *cmd* 'LIST' [b'1 8526'] *cmd* 'RETR 1' From: QQ邮箱团队 <10000@qq.com> To: 思 <3xxxxde4e4@qq.com> Subject: 更安全、更高效、更强大,尽在QQ邮箱APP Text: ... b'+OK Bye'



