python发送邮件

当我们开发一个程序时,有时我们需要开发一些自动化的任务。执行完成后,系统会自动将结果发送电子邮件。Python使用smtplib模块发送电子邮件,这是一个标准包。您可以直接导入。
以下所有代码亲测有效。

1.简化版发送邮件

import smtplib
from email.mime.text import MIMEText
#  构造消息内容,使用163邮箱发送邮件给QQ邮箱实测成功
email_host = 'smtp.163.com'  #  邮件的smtp地址
email_user = 'xxxxxxx@163.com'  #  发送方账户
email_pwd = 'xxxxxxx'  #  发送方账户密码
maillist = 'xxxxxxx@qq.com' #  收件人邮箱,如果有多个账户,用英文逗号分隔
me = email_user
msg = MIMEText('hello, andy')  #  电子邮件的内容
#  Mintest被实例化,然后实例化为msg
msg['Subject'] = 'I am MeiMei'  #  邮件主题
msg['From'] = me  #  发送方账户
msg['To'] = maillist  #  收件人账户列表
smtp = smtplib.SMTP(email_host, port=25)  #  连接邮箱、接收邮箱地址和端口号,smtp的端口号为25
smtp.login(email_user, email_pwd)  #  发件人的电子邮件帐户和密码
smtp.sendmail(me,maillist,msg.as_string()) #  参数是发送方和接收方,第三个参数是将上面发送的电子邮件的内容更改为字符串
smtp.quit()  #  发送后退出smtp
print('email send success.')

2.简化版发送带有txt附件的邮件

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
#  用于发送带有附件的电子邮件
#  构造消息内容,使用163邮箱发送邮件给QQ邮箱实测成功
email_host = 'smtp.163.com'  #  邮件的smtp地址
email_user = 'xxxxxxx@163.com'  #  发送方账户
email_pwd = 'xxxxxxx'  #  发送方账户密码
maillist = 'xxxxxxx@qq.com' #  收件人邮箱,如果有多个账户,用英文逗号分隔

new_masg=MIMEMultipart()
#  构造一个可以发送附件的对象
new_masg.attach(MIMEText('There are attachments in this message'))
#  电子邮件的内容
me = email_user
#  msg = MIMEText('hello') # 邮件内容
#  Mintest被实例化,然后实例化为msg
new_masg['Subject'] = 'I am MeiMei'  #  邮件主题
new_masg['From'] = me  #  发送方账户
new_masg['To'] = maillist  #  收件人账户列表
att=MIMEText(open('a.txt').read())
att["Content-Type"] = 'application/octet-stream'
# 发附件的时候一定要这样写
att["Content-Disposition"] = 'attachment; filename="a.txt"'
new_masg.attach(att)
smtp = smtplib.SMTP(email_host, port=25)  #  连接邮箱、收信箱地址、端口号,smtp的端口号为25
smtp.login(email_user, email_pwd)  #  发件人的电子邮件帐户和密码
smtp.sendmail(me,maillist,new_masg.as_string())
#  参数是sender和receiver,第三个是把上面发送的email的内容改成字符串
smtp.quit()  #  发送后退出smtp
print('email send success.')

3.简化版发送csv文件

假如要发送csv内容,文件名位contact.csv,内容为:

name,email,grade
Ron Obvious,my+ovious@gmail.com,B+
Killer Rabbit of Caerbannog,my+rabbit@gmail.com,A
Brian Cohen,my+brian@gmail.com,C

以下代码示例可让您向多个联系人发送个性化电子邮件。它为每个联系人循环一个带有姓名、电子邮件、等级的 CSV 文件。

通用消息在脚本的开头定义,并为 CSV 文件中的每个联系人填写其 {name}{grade} 占位符,并通过与 mail 服务器的安全连接发送个性化电子邮件,如你之前看过:

import csv, smtplib, ssl

message = """Subject: Your grade
Hi {name}, your grade is {grade}"""
from_address = "my@gmail.com"
password = input("Type your password and press enter: ")

context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(from_address, password)
    with open("contacts_file.csv") as file:
        reader = csv.reader(file)
        next(reader)  # 跳过标题行
        for name, email, grade in reader:
            server.sendmail(
                from_address,
                email,
                message.format(name=name,grade=grade),
            )

4.加强版本发送邮件

当然,我们可以把它封装成一个函数。使用时直接调用函数,传入邮箱账号密码、收件人、发件人、标题、附件和内容。
这个类没有异常处理,朋友们可以自己做异常处理。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
class SendMail(object):
    def __init__(self,username,passwd,recv,content,title,file=None,
                 email_host='smtp.163.com',port=25):
        self.username = username     #  发件人帐户
        self.passwd = passwd         #  发件人帐户密码
        self.recv = recv             #  接收电子邮件帐户
        self.title = title           #  电子邮件主题
        self.file = file             #  附件
        self.content = content       #  电子邮件的内容
        self.email_host = email_host     # smtp
        self.port = port
    def send_mail(self):
        #  以下是发送附件的内容
        msg=MIMEMultipart()
        if self.file:
            att = MIMEText(open(self.file).read())          #  附件可能不存在,所以您需要尝试
            att["Content-Type"] = 'application/octet-stream'
            #  发送附件时必须这样写
            att["Content-Disposition"] = 'attachment; filename="%s"'%self.file

            msg.attach(att)
        #  以下是正文
        msg.attach(MIMEText(self.content))
        msg['Subject'] = self.title #  电子邮件主题
        msg['From'] = self.username  #  发送方账户
        msg['To'] = self.recv  #  收件人帐户列表
        self.smtp=smtplib.SMTP(self.email_host,port=self.port)
        #  发送邮件服务的目标
        self.smtp.login(self.username,self.passwd)
        self.smtp.sendmail(self.username,self.recv,msg.as_string())
    def __del__(self):
        self.smtp.quit()

if __name__ == '__main__':
    m = SendMail(
        username='xxxxxx@163.com',passwd='xxxxxxx',recv='xxxxxx@qq.com', file="a.txt",
        title='This is an email from the class', content='Pan Yang is a big beauty', email_host='smtp.163.com')
    m.send_mail()

5.加强版本发送带有附件(txt或者pdf)邮件

为了将二进制文件发送到旨在处理文本数据的电子邮件服务器,它们需要在传输之前进行编码。这通常使用 base64 来完成,它将二进制数据编码为可打印的 ASCII 字符。

#!/usr/bin/python3
import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.mime.base import MIMEBase

# 方法一:使用sendmail
class SendMail(object):
    def __init__(self, username, passwd, recv, content, title, file=None,
                 email_host='smtp.163.com', port=25, content_subtype="plain"):
        self.username = username  # 发送方账户
        self.passwd = passwd  # 发送方账户密码
        self.recv = recv  # 接收邮件账户可以是列表
        self.title = title  # 邮件主题
        self.file = file  # 附件
        self.content = content  # 邮件正文
        self.email_host = email_host  # smtp
        self.port = port
        self.content_subtype = content_subtype  # 正文类型 html,plain

    def send_mail(self):
        #  以下是发送内容的附件
        msg = MIMEMultipart()
        if self.file:
            # 判断是txt文件还是pdf文件
            if self.file.endswith(".txt"):
                try:
                    att = MIMEText(open(self.file, mode='rb').read(), "base64", "utf-8")  # 附件可能不存在,所以您需要尝试
                except Exception as e:
                    raise Exception(f"open {self.file} Error!")
                else:
                    att["Content-Type"] = 'application/octet-stream'
                    #  发送附件时必须这样写
                    # 附件名称非中文时的写法
                    # att["Content-Disposition"] = 'attachment; filename="%s"' % self.file
                    # 附件名称为中文时的写法
                    att.add_header("Content-Disposition", "attachment", filename=("gbk", "", f"{self.file}"))

                    msg.attach(att)
            elif self.file.endswith(".pdf"):
                try:
                    # 以二进制模式打开PDF文件
                    with open(self.file, "rb") as attachment:
                        # 添加文件作为application/octet-stream
                        # 电子邮件客户端通常可以自动下载此附件
                        part = MIMEBase("application", "octet-stream")
                        part.set_payload(attachment.read())
                except Exception as e:
                    raise Exception(f"open {self.file} Error!")
                else:
                    # 添加头作为键/值对到附件part
                    # 附件名称为中文时的写法
                    part.add_header("Content-Disposition", "attachment", filename=("gbk", "", f"{self.file}"))
                    # 以 ASCII 字符编码文件以通过电子邮件发送
                    encoders.encode_base64(part)

                    # 附件名称非中文时的写法
                    # part.add_header(
                    #     "Content-Disposition",
                    #     f"attachment; filename= {self.file}",
                    # )

                    # 向消息添加附件
                    msg.attach(part)
        #  以下是正文
        msg.attach(MIMEText(self.content, self.content_subtype))
        msg['Subject'] = self.title  # 电子邮件主题
        msg['From'] = self.username  # 发送方账户
        msg['To'] = self.recv  # 收件人帐户列表
        msg["Bcc"] = self.recv  # 群发电子邮件推荐
        self.smtp = smtplib.SMTP(self.email_host, port=self.port)
        #  发送邮件服务的目标
        self.smtp.login(self.username, self.passwd)
        self.smtp.sendmail(self.username, self.recv, msg.as_string())

    def __del__(self):
        self.smtp.quit()

# 方法二:使用SMTP_SSL
class SendMailSSL(object):
    def __init__(self, username, passwd, recv, content, title, file=None,
                 email_host='smtp.163.com', port=465, content_subtype="plain"):
        self.username = username  # 发送方账户
        self.passwd = passwd  # 发送方账户密码
        self.recv = recv  # 接收邮件账户可以是列表
        self.title = title  # 邮件主题
        self.file = file  # 附件
        self.content = content  # 邮件正文
        self.email_host = email_host  # smtp
        self.port = port
        self.content_subtype = content_subtype  # 正文类型 html,plain

    def send_mail(self):
        #  以下是发送内容的附件
        msg = MIMEMultipart()
        if self.file:
            if self.file.endswith(".txt"):
                try:
                    att = MIMEText(open(self.file, "rb").read(), "base64", "utf-8")  # 附件可能不存在,所以您需要尝试
                except Exception as e:
                    raise Exception(f"open {self.file} Error!")
                else:
                    att["Content-Type"] = 'application/octet-stream'
                    #  发送附件时必须这样写
                    # 附件名称非中文时的写法
                    # att["Content-Disposition"] = 'attachment; filename="%s"' % self.file
                    # 附件名称为中文时的写法
                    att.add_header("Content-Disposition", "attachment", filename=("gbk", "", f"{self.file}"))

                    msg.attach(att)
            elif self.file.endswith(".pdf"):
                try:
                    # 以二进制模式打开PDF文件
                    with open(self.file, "rb") as attachment:
                        # 添加文件作为 application/octet-stream
                        # 电子邮件客户端通常可以将其作为附件自动下载
                        part = MIMEBase("application", "octet-stream")
                        part.set_payload(attachment.read())
                except Exception as e:
                    raise Exception(f"open {self.file} Error!")
                else:
                    # 添加头作为键/值对到附件part
                    # 附件名称为中文时的写法
                    part.add_header("Content-Disposition", "attachment", filename=("gbk", "", f"{self.file}"))
                    # Encode file in ASCII characters to send by email
                    encoders.encode_base64(part)

                    # 附件名称非中文时的写法
                    # part.add_header(
                    #     "Content-Disposition",
                    #     f"attachment; filename= {self.file}",
                    # )

                    # 向消息添加附件
                    msg.attach(part)
        #  以下是正文
        msg.attach(MIMEText(self.content, self.content_subtype))
        msg['Subject'] = self.title  # 电子邮件主题
        msg['From'] = self.username  # 发送方账户
        msg['To'] = self.recv  # 收件人帐户列表
        msg["Bcc"] = self.recv  # 群发电子邮件推荐
        context = ssl.create_default_context()
        with smtplib.SMTP_SSL(self.email_host, port=self.port, context=context) as self.smtp:
            # 发送邮件服务的目标
            self.smtp.login(self.username, self.passwd)
            self.smtp.sendmail(self.username, self.recv, msg.as_string())


if __name__ == '__main__':
	# 使用方法一SendMail
    m = SendMail(
        username='xxxx@163.com', passwd='xxxx', recv='xxxxx@qq.com', file="xxx.txt",
        title='This is an email from the class demo', content='LULU is a big beauty', email_host='smtp.163.com')
    m.send_mail()
	# 使用方法二SendMailSSL
    content = """\
                Subject: Hi there

                This message is sent from Python."""
    text = """\
        Hi,
        How are you?
        Real Python has many great tutorials:
        www.realpython.com"""
    html = """\
        <html>
          <body>
            <p>Hi,<br>
               How are you?<br>
               <a href="http://www.realpython.com">Real Python</a> 
               has many great tutorials.
            </p>
          </body>
        </html>
        """
    m_ssl = SendMailSSL(
        username='xxxxxx@163.com', passwd='xxxxxx', recv='xxxxx@qq.com', file="xxxx.pdf",
        title='This is an email from the class demo', content=html, email_host='smtp.163.com', content_subtype="html")
    m_ssl.send_mail()

参考目录

https://www.programmerall.com/article/2177239137/
https://realpython.com/python-send-email/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值