【Python学习】电子邮件

SMTP发送邮件

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。Python对SMTP支持有smtplibemail两个模块,email负责构造邮件,smtplib负责发送邮件。

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
  • host - 这是运行SMTP服务器的主机。可以指定主机的IP地址或域名。这是一个可选参数。
  • port- 如果提供主机参数,则需要指定SMTP服务器正在侦听的端口。通常这个端口默认值是:25
  • local_hostname -如果SMTP服务器在本地计算机上运行,那么可以只指定localhost选项。

1、发送纯文本文件

  • 给单人发送邮件
#! /usr/bin/env python
# coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

# qq邮箱smtp服务器
host_server = 'smtp.qq.com'
# sender_qq为发件人的qq号码
sender_qq = '...@qq.com'
# pwd为qq邮箱的授权码
pwd = 'nz....hf'  ## nz....hf
# 发件人的邮箱
sender_qq_mail = '..@qq.com'
# 收件人邮箱
receiver = '183...@163.com'

# 邮件的正文内容
mail_content = '你好,这是使用python登录qq邮箱发邮件的测试'
# 邮件标题
mail_title = 'Eureka的邮件'

# ssl登录
smtp = SMTP_SSL(host_server)
# set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = receiver
smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

  • 群发邮件
#! /usr/bin/env python
#coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL


#qq邮箱smtp服务器
host_server = 'smtp.qq.com'
#sender_qq为发件人的qq号码
sender_qq = '...@qq.com'
#pwd为qq邮箱的授权码
pwd = 'nzi...bchf'
#发件人的邮箱
sender_qq_mail = '...@qq.com'
#收件人邮箱(读取脚本)
with open('D:/code/PycharmProjects/PythonStudy/venv/Include/电子邮件/email.txt') as f:
    for email in f.readlines():
        emails = email.strip(',')

receivers = list(emails.split(','))

#邮件的正文内容
mail_content = 'Hi,使用Python登录qq邮箱群发邮件的测试'
#邮件标题
mail_title = '^_^的邮件'


#ssl登录
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("receivers test", 'utf-8') ## 接收者的别名
smtp.sendmail(sender_qq_mail, receivers, msg.as_string())
smtp.quit()
  • 发送HTML格式的邮件
#! /usr/bin/env python
# coding=utf-8

from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

# qq邮箱smtp服务器
host_server = 'smtp.qq.com'
# sender_qq为发件人的qq号码
sender_qq = '...@qq.com'
# pwd为qq邮箱的授权码
pwd = 'nz...hf'
# 发件人的邮箱
sender_qq_mail = '...@qq.com'
# 收件人邮箱
with open('D:/code/PycharmProjects/PythonStudy/venv/Include/电子邮件/email.txt') as f:
    for email in f.readlines():
        emails = email.strip(',')

receiver = list(emails.split(','))

# 邮件的正文内容
mail_content = "你好,<p>这是使用python登录qq邮箱发送HTML格式邮件的测试:</p><p><a href='http://www.baidu.com'>baidu</a></p><img src='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1583990072584&di=cfc04c054a9f33fb000fd4f207c70ff9&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20190715%2F0c2b2d67886c4d72a90fee16e3fc8659.jpeg'></p>"
# 邮件标题
mail_title = 'Python测试HTML邮件'

# ssl登录
smtp = SMTP_SSL(host_server)
# set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

msg = MIMEText(mail_content, "html", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8') # 发送者别名
msg["From"] = sender_qq_mail
msg["To"] = Header("receiver test", 'utf-8')  # 接收者的别名

smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

  • 发送带附件的邮件
    发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后使用smtplib.smtp发送:
#! /usr/bin/env python
# coding=utf-8
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

# qq邮箱smtp服务器
host_server = 'smtp.qq.com'
# sender_qq为发件人的qq号码
sender_qq = '...@qq.com'
# pwd为qq邮箱的授权码
pwd = 'nz...chf'
# 发件人的邮箱
sender_qq_mail = '...@qq.com'
# 收件人邮箱
with open('D:/code/PycharmProjects/PythonStudy/venv/Include/电子邮件/email.txt') as f:
    for email in f.readlines():
        emails = email.strip(',')

receiver = list(emails.split(','))

# 邮件的正文内容
mail_content = "你好,<p>这是使用python登录qq邮箱发送HTML格式邮件的测试</p><img src='https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1583990072584&di=cfc04c054a9f33fb000fd4f207c70ff9&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20190715%2F0c2b2d67886c4d72a90fee16e3fc8659.jpeg'></p>"
# 邮件标题
mail_title = 'Python测试HTML邮件'

# 邮件正文内容
msg = MIMEMultipart()
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_qq_mail
msg["To"] = Header("receiver test", 'utf-8')  ## 接收者的别名
msg.attach(MIMEText(mail_content, 'html', 'utf-8'))

# 构造附件1,传送当前目录下的 email.txt 文件
att1 = MIMEText(open('email.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="email.txt"'
msg.attach(att1)

# 构造附件2,传送当前目录下的 demo.txt 文件
att2 = MIMEText(open('demo.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="demo.txt"'
msg.attach(att2)

# ssl登录
smtp = SMTP_SSL(host_server)
# set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(1)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)

smtp.sendmail(sender_qq_mail, receiver, msg.as_string())
smtp.quit()

POP3收取邮件

Python内置一个poplib模块,实现了POP3协议,可以直接用来收邮件

  • 收取邮件分两步:
    1、用poplib把邮件的原始文本下载到本地;
    2、用email解析原始文本,还原为邮件对象。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr

import poplib

# 输入邮件地址, 口令和POP3服务器地址:
email = '...@qq.com'
password = 'nzii...bchf'
pop3_server = 'smtp.qq.com'


def guess_charset(msg):
	# 得到字符集
    charset = msg.get_charset()
    if charset is None:
    	 # lower:所有大写字符为小写
        content_type = msg.get('Content-Type', '').lower()
        # find:检测字符串中是否包含子字符串
        # 返回charset=头字符的位置
        pos = content_type.find('charset=')
        if pos >= 0:
        	# strip:移除字符串头尾指定的字符(默认为空格)
            charset = content_type[pos + 8:].strip()
    return charset


def decode_str(s):
    value, charset = decode_header(s)[0]
    if charset:
        value = value.decode(charset)
    return value

# 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:
                	# parseaddr:解析字符串中的email地址
                    hdr, addr = parseaddr(value)
                    # 解码主题
                    name = decode_str(hdr)
                     # 合成内容
                    value = u'%s <%s>' % (name, addr)
            print('%s%s: %s' % ('  ' * indent, header, value))
     # 如果消息由多个部分组成,则返回True
    if (msg.is_multipart()):
    	# 返回list,包含所有的子对象
        parts = msg.get_payload()
        # enumerate将其组成一个索引序列,利用它可以同时获得索引和值
        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':
        	 # 返回list,包含所有的子对象,开启解码
            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))


# 连接到POP3服务器:
server = poplib.POP3_SSL(pop3_server, port=995)
# 可以打开或关闭调试信息:
server.set_debuglevel(1)
# 可选:打印POP3服务器的欢迎文字:
print(server.getwelcome().decode('utf-8'))
# 身份认证:
server.user(email)
server.pass_(password)
# stat()返回邮件数量和占用空间:
print('Messages: %s. Size: %s' % server.stat())
# list()返回所有邮件的编号:
resp, mails, octets = server.list()
# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
print(mails)
# 获取最新一封邮件, 注意索引号从1开始:
index = len(mails)
resp, lines, octets = server.retr(index)
# lines存储了邮件的原始文本的每一行,
# 可以获得整个邮件的原始文本:
msg_content = b'\r\n'.join(lines).decode('utf-8')
# 稍后解析出邮件:
msg = Parser().parsestr(msg_content)

if __name__ == '__main__':
    print_info(msg)
# 可以根据邮件索引号直接从服务器删除邮件:
# server.dele(index)
# 关闭连接:
server.quit()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值