跳至主要内容

实战 之 python发邮件


资料

https://www.thepythoncorner.com/2019/10/the-detailed-guide-on-sending-emails-from-your-python-app/

https://blog.mailtrap.io/sending-emails-in-python-tutorial-with-code-examples/

https://realpython.com/python-send-email/

http://www.pybloggers.com/2018/12/sending-emails-with-python/

https://www.runoob.com/python3/python3-smtp.html

https://docs.python.org/3/library/email.examples.html#email-examples

https://docs.python.org/3.7/library/email.message.html

https://glowingpython.blogspot.com/2011/05/how-to-use-strings-template.html

https://www.python.org/dev/peps/pep-0292/



企业邮箱常见的错误提示


gmail(google.com)
POP3服务器地址:pop.gmail.com(SSL启用 端口:995)
SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587)
 
163
POP3服务器地址:pop.163.com(端口:110)
SMTP服务器地址:smtp.163.com(端口:25)

QQ邮箱
POP3服务器地址:pop.qq.com(端口:110)
SMTP服务器地址:smtp.qq.com (端口:25)

https://github.com/leemunroe/responsive-html-email-template

终版发邮件

(联系人contacts.csv、多语言模板mail_template_x.html、多个不同类型的附件)

文件
/E:.
│  python-send-mail.py
│  
├─attachment
│      Ansible From Beginner to Pro.pdf.pdf
│      鼠年.jpg
│      
├─contact
│      contacts.csv
│      
├─mail_template
│      mail_template_cn.html
│      mail_template_en.html
│      mail_template_jp.html
│      
└─subject
        subjects.txt
contacts.csv
name,email,country
DT,2818686037@qq.com,CN
JOLIN,jk.d@aisino.sh.cn,JP
admin,solopythonlearning@gmail.com,XX

mail_template.txt
:
    thanks for your order! We are processing it now and will contact you soon.

mail_template_en.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
    <body>
        <p>Hi $PERSON_NAME:<br>&nbsp;&nbsp;thanks for your order! We are <strong>processing</strong> it now and will contact you soon.</p>
        <p>
        <a href="https://blog.example.com/send-email-python/">How to Send Emails with Python?</a>
        </p>
    </body>
</html>

mail_template_cn.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
    <body>
        <p>$PERSON_NAME,您好 :<br>&nbsp;&nbsp;感谢您的订单!我们正在<strong>处理</strong>它,并将尽快与您联系。</p>
        <p>
        <a href="https://blog.example.com/send-email-python/">如何使用Python发送电子邮件?</a>
        </p>
    </body>
</html>

mail_template_jp.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
    <body>
        <p>こんにちは$PERSON_NAME:<br>&nbsp;&nbsp;ご注文ありがとうございます! 現在<strong>処理</strong>中です。間もなくご連絡いたします。</p>
        <p>
        <a href="https://blog.example.com/send-email-python/">Pythonでメールを送信する方法は?</a>
        </p>
    </body>
</html>
subjects.txt
{"CN": "订单确认", "JP": "注文確認", "EN": "Order confirmation"}






源码 mail.py 名称中不能出现导入的类名譬如python-send-email.py




import os, csv, json, smtplib
from os.path import join, dirname, abspath, basename
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders


smtp_host = 'smtp.aisino.sh.cn'
port = 25

# 发件人邮箱账号和密码
MY_ADDRESS = 'jk.d@aisino.sh.cn'
PASSWORD = 'xxx'

# 抄送:收件人能看到抄送人,抄送人也能看到收件人
# 英文是cc(Carbon copy)
CC = '744351600@qq.com'
# 密送:收件人和抄送人都看不到密送人,密送人能看到收件人和抄送人
# 英文是bcc(blind carbon copy)
BCC = 'jk.d@aisino.sh.cn'

# 邮件计数
count = 0

# 根据当前目录获取联系人、邮件模板、附件、主题目录
base_dir = dirname(abspath(__file__))
contact_path = join(base_dir, 'contact')
template_path = join(base_dir, 'mail_template')
attachment_path = join(base_dir, 'attachment')
subject_path = join(base_dir, 'subject')


def get_contacts(filename):
    """
    返回三个列表名称:names、emails、countrys
    从文件名指定的文件中读取
    """  
    names = []
    emails = []
    countrys = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        reader = csv.reader(contacts_file)
        # 调试
        #for row in reader:
        #    print(row)
        # 跳过标题行
        next(reader)
        for name, email, country in reader:
            names.append(name)
            emails.append(email)
            countrys.append(country)
    return names, emails, countrys


def read_template(filename):
    """
    返回包含以下内容的Template对象
    文件名指定的文件
    """   
    with open(filename, mode='r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


def add_attachment(filelist):
    """
    返回一个附件列表:parts
    """  
    parts = []
    for filename in filelist:
        # 附件位于该Python脚本的目录中
        # 以二进制模式打开附件
        with open(filename, mode="rb") as attachment:
            # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
            part = MIMEBase('application', 'octet-stream')
            part.set_payload(attachment.read())
            # base64编码
            encoders.encode_base64(part)
            # 添加头参数,gbk支持中文附件名
            part.add_header(
                'Content-Disposition',
                # f"attachment; filename= {filename}",
                'attachment',
                filename=('gbk', '', basename(filename))
            )
            parts.append(part)
    return parts


def get_subject(filename):
    """
    返回一个主题字典:subject
    """  
    with open(filename, mode='r', encoding='utf-8') as subject_file:
        subject = json.load(subject_file)
    return subject


def main():
    # 获取联系人信息
    names, emails, countrys = get_contacts(join(contact_path, 'contacts.csv'))
    # 获取主题
    SUBJECT = get_subject(join(subject_path, 'subjects.txt'))
    # message_template = read_template('mail_template.html')
    # 添加任意类型(pdf、office、rar、zip、jpg等)附件并存放入列表list_attachment,支持中文
    # attachment_list = ['Ansible From Beginner to Pro.pdf',  'year-of-the-rat-2020.jpg']
    attachment_list = []
    for root, dirs, files in os.walk(attachment_path, topdown=False):
        # print(root,dirs,files)
        for name in files:
            print(join(root,name))
            attachment_list.append(join(root,name))
    parts = add_attachment(attachment_list)
    # 设置SMTP服务器
    with smtplib.SMTP(smtp_host, port) as smtp_server:
        smtp_server.login(MY_ADDRESS, PASSWORD)
        # 为每个联系人发送电子邮件
        for name, email, country in zip(names, emails, countrys):
            # 创建一条message
            message = MIMEMultipart()
            # 根据country字段选择对应的邮件模板和主题
            if country == 'CN':
                message_template = read_template(join(template_path,'mail_template_cn.html'))
                message['Subject'] = SUBJECT['CN']
            elif country == 'JP':
                message_template = read_template(join(template_path,'mail_template_jp.html'))
                message['Subject'] = SUBJECT['JP'] 
            else :
                message_template = read_template(join(template_path,'mail_template_en.html'))
                message['Subject'] = SUBJECT['EN']
            # 将实际的人名添加到消息模板中  
            msg = message_template.substitute(PERSON_NAME=name.title())
            # 如果模板read_template('mail_template.txt')则用 msg = 'Hi ' + name + message_template.substitute(PERSON_NAME=name.title())
            # 打印出邮件正文
            print(msg)
            # 设置message的参数:发件人、收件人、抄送、密送
            message['From'] = MY_ADDRESS
            message['To'] = email
            message['Cc'] = CC
            message['Bcc'] = BCC
            # message['Subject'] = SUBJECT
            # 添加message正文    
            message.attach(MIMEText(msg, 'html'))
            # 如果模板read_template('mail_template.txt')则用message.attach(MIMEText(msg, 'plain'))
            # 在邮件中添加附件并将其转换为字符串
            for part in parts:
                message.attach(part)
                text = message.as_string()
            # 通过先前设置的服务器发送邮件
            smtp_server.sendmail(MY_ADDRESS, [email, CC, BCC], text)
            # 不用text的话,也可以这样发邮件smtp_server.send_message(message)
            print(f'\nEmail successfully sent to {name}:{email}!')
            print('-'*100)
            
            global count
            count += 1
    print(f'本次共发送 {count} 封邮件!')


if __name__ == '__main__':
    main()

-----------------------------------------------------
import os, csv, smtplib
from os.path import join, dirname, abspath
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

smtp_host = 'smtp.aisino.sh.cn'
port = 25
# 邮箱账号和密码
MY_ADDRESS = 'jk.d@aisino.sh.cn'
PASSWORD = 'xxx'
# 抄送地址
CC = '744351600@qq.com'
# 邮件主题
SUBJECT = {'CN':"订单确认",
           'JP':"注文確認",
           'EN':"Order confirmation"}

# 根据当前目录获取联系人、模板、附件目录
base_dir = dirname(abspath(__file__))
contact_path = join(base_dir, 'contact')
template_path = join(base_dir, 'mail_template')
attachment_path = join(base_dir, 'attachment')

def get_contacts(filename):
    """
    返回三个列表名称:names、emails、countrys
    从文件名指定的文件中读取
    """  
    names = []
    emails = []
    countrys = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        reader = csv.reader(contacts_file)
        # 跳过标题行
        next(reader)
        for name, email, country in reader:
            names.append(name)
            emails.append(email)
            countrys.append(country)
    return names, emails, countrys


def read_template(filename):
    """
    返回包含以下内容的Template对象
    文件名指定的文件
    """   
    with open(filename, 'r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


def add_attachment(filelist):
    """
    返回一个附件列表 parts
    """  
    parts = []
    for filename in filelist:
        # 附件位于该Python脚本的目录中
        # 以二进制模式打开附件
        with open(filename, "rb") as attachment:
            # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
            part = MIMEBase("application", "octet-stream")
            part.set_payload(attachment.read())
            # base64编码
            encoders.encode_base64(part)
            # 添加头参数,gbk支持中文附件名
            part.add_header(
                "Content-Disposition",
                # f"attachment; filename= {filename}",
                "attachment",
                filename=('gbk', '', os.path.basename(filename))
            )
            parts.append(part)
    return parts


def main():
    # 读取联系人、邮件模板、附件
    names, emails, countrys = get_contacts(join(contact_path, 'contacts.csv'))
    # message_template = read_template('mail_template.html')
    # 添加任意类型(pdf、office、rar、zip、jpg等)附件并存放入列表list_attachment,支持中文
    # attachment_list = ['Ansible From Beginner to Pro.pdf',  'year-of-the-rat-2020.jpg']
    attachment_list = []
    for root, dirs, files in os.walk(attachment_path, topdown=False):
        # print(root,dirs,files)
        for name in files:
            print(join(root,name))
            attachment_list.append(os.path.join(root,name))
    parts = add_attachment(attachment_list)
    # 设置SMTP服务器
    with smtplib.SMTP(smtp_host, port) as smtp_server:
        smtp_server.login(MY_ADDRESS, PASSWORD)
        # 为每个联系人发送电子邮件
        for name, email, country in zip(names, emails, countrys):
            # 创建一条message
            message = MIMEMultipart()
            # 根据country选择对应的邮件模板和主体
            if country == 'CN':
                message_template = read_template(join(template_path,'mail_template_cn.html'))
                message['Subject'] = SUBJECT['CN']
            elif country == 'JP':
                message_template = read_template(join(template_path,'mail_template_jp.html'))
                message['Subject'] = SUBJECT['JP'] 
            else :
                message_template = read_template(join(template_path,'mail_template_en.html'))
                message['Subject'] = SUBJECT['EN']
            # 将实际的人名添加到消息模板中  
            msg = message_template.substitute(PERSON_NAME=name.title())
            # 如果模板read_template('mail_template.txt')则用 msg = 'Hi ' + name + message_template.substitute(PERSON_NAME=name.title())
            # 打印出邮件正文
            print(msg)
            # 设置message的参数:发件人、收件人、抄送
            message['From'] = MY_ADDRESS
            message['To'] = email
            message['Cc'] = CC
            # message['Subject'] = SUBJECT          
            # 添加message正文    
            message.attach(MIMEText(msg, 'html'))
            # 如果模板read_template('mail_template.txt')则用message.attach(MIMEText(msg, 'plain'))
            # 在邮件中添加附件并将其转换为字符串
            for part in parts:
                message.attach(part)
                text = message.as_string()
            # 通过先前设置的服务器发送邮件
            smtp_server.sendmail(MY_ADDRESS, [email, CC], text)
            # 不用text的话,也可以这样发邮件smtp_server.send_message(message)
            print(f'\nEmail successfully sent to {name}:{email}!')
            print('-'*100)

    
if __name__ == '__main__':
    main()

--------------------------------------------------------
import smtplib,csv
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders


smtp_host = 'smtp.aisino.sh.cn'
port = 25
# 邮箱账号和密码
MY_ADDRESS = 'jk.d@aisino.sh.cn'
PASSWORD = 'xxx'
# 抄送地址
CC = '744351600@qq.com'
# 邮件主题
SUBJECT = {'CN':"订单确认",
           'JP':"注文確認",
           'EN':"Order confirmation"}

def get_contacts(filename):
    """
    返回三个列表名称:names、emails、countrys
    从文件名指定的文件中读取
    """  
    names = []
    emails = []
    countrys = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        reader = csv.reader(contacts_file)
        # 跳过标题行
        next(reader)
        for name, email, country in reader:
            names.append(name)
            emails.append(email)
            countrys.append(country)
    return names, emails, countrys


def read_template(filename):
    """
    返回包含以下内容的Template对象
    文件名指定的文件
    """   
    with open(filename, 'r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


def add_attachment(filelist):
    """
    返回一个附件列表 parts
    """  
    parts = []
    for filename in filelist:
        # 附件位于该Python脚本的目录中
        # 以二进制模式打开附件
        with open(filename, "rb") as attachment:
            # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
            part = MIMEBase("application", "octet-stream")
            part.set_payload(attachment.read())
            # base64编码
            encoders.encode_base64(part)
            # 添加头参数,gbk支持中文附件名
            part.add_header(
                "Content-Disposition",
                "attachment",
                filename=('gbk', '', filename)
#                f"attachment; filename= {filename}",
            )
            parts.append(part)
    return parts


def main():
    # 读取联系人、邮件模板、附件
    names, emails, countrys = get_contacts('contacts.csv')
#    message_template = read_template('mail_template.html')
    # 添加任意类型(pdf、office、rar、zip、jpg等)附件并存放入列表list_attachment,支持中文
    attachment_list = ['电子发票平台使用手册.pdf',  '01-安-电子发票平台服务及架构演进-20190711.pptx']
    parts = add_attachment(attachment_list)
    # 设置SMTP服务器
    with smtplib.SMTP(smtp_host, port) as smtp_server:
        smtp_server.login(MY_ADDRESS, PASSWORD)
        # 为每个联系人发送电子邮件
        for name, email, country in zip(names, emails, countrys):
            # 创建一条message
            message = MIMEMultipart()
            # 根据country选择对应的邮件模板和主体
            if country == 'CN':
                message_template = read_template('mail_template_cn.html')
                message['Subject'] = SUBJECT['CN']
            elif country == 'JP':
                message_template = read_template('mail_template_jp.html')
                message['Subject'] = SUBJECT['JP'] 
            else :
                message_template = read_template('mail_template_en.html')
                message['Subject'] = SUBJECT['EN']
            # 将实际的人名添加到消息模板中  
            msg = message_template.substitute(PERSON_NAME=name.title())
            # 如果模板read_template('mail_template.txt')则用 msg = 'Hi ' + name + message_template.substitute(PERSON_NAME=name.title())
            # 打印出邮件正文
            print(msg)
            # 设置message的参数:发件人、收件人、抄送
            message['From'] = MY_ADDRESS
            message['To'] = email
            message['Cc'] = CC
#            message['Subject'] = SUBJECT          
            # 添加message正文    
            message.attach(MIMEText(msg, 'html'))
            # 如果模板read_template('mail_template.txt')则用message.attach(MIMEText(msg, 'plain'))
            # 在邮件中添加附件并将其转换为字符串
            for part in parts:
                message.attach(part)
                text = message.as_string()
            # 通过先前设置的服务器发送邮件
            smtp_server.sendmail(MY_ADDRESS, [email, CC], text)
            # 不用text的话,也可以这样发邮件smtp_server.send_message(message)
            print(f'\nEmail successfully sent to {name}:{email}!')
            print('-'*100)

    
if __name__ == '__main__':
    main()





发送简单邮件


import smtplib

smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定发件人和收件人的电子邮件地址
sender = "jk.d@aisino.sh.cn"
receiver = "2818686037@qq.com"

# meesage中的From、To顺序不能变且中间没空格,有空格则会把From、To写到信中,Subject可在它们前面或者后面,使用至少一个换行符(\ n)将主题与消息正文分开,本例使用了两个换行符,并使用'f'自动在文本中插入变量
message = f"""\
From: {sender}
To: {receiver}
Subject: Hi there


This is my first message with Python."""

# 使用上面指定的凭据发送邮件
with smtplib.SMTP(smtp_server, port) as server:
        server.login(login, password)
        server.sendmail(sender, receiver, message)
print('Sent')


发信给多个收件人

Python脚本所在的文件夹中contacts.csv内容如下
#name,email
DT,2818686037@qq.com
JOLIN,jk.d@aisino.sh.cn


import csv, smtplib

smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定发件人的电子邮件地址
sender = "jk.d@aisino.sh.cn"

# meesage中的From、To顺序不能变且中间没空格,有空格则会把From、To写到信中,Subject可在它们前面或者后面,使用至少一个换行符(\ n)将主题与消息正文分开
message = """Subject: Order confirmation
From: {sender}
To: {recipient}

Hi {name}:
    thanks for your order! We are processing it now and will contact you soon"""
with smtplib.SMTP(smtp_server, port) as server:
    server.login(login, password)
    with open("contacts.csv") as file:
        reader = csv.reader(file)
        next(reader)  # it skips the header row
        for name, email in reader:
            server.sendmail(
              sender,
              email,
              message.format(name=name, recipient=email, sender=sender)
            )
            print(f'Sent to {name}')



添加HTML内容



import smtplib
from email.mime.text import MIMEText 
from email.mime.multipart import MIMEMultipart

smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定发件人和收件人的电子邮件地址
sender_email = "jk.d@aisino.sh.cn" 
receiver_email = "2818686037@qq.com"

message = MIMEMultipart("alternative") 
message["Subject"] = "multipart test3" 
message["From"] = sender_email 
message["To"] = receiver_email 

# 编写纯文本部分 
text = """\
Hi, Check out the new post on our blog blog: How to Send Emails with Python? https://blog.example.com/send-email-python/ Feel free to let us know what content would be useful for you!""" 

# 编写HTML部分
html = """\
<html> <body> <p>Hi,<br> Check out the new post on our blog blog: </p> <p><a href="https://blog.example.com/send-email-python/">How to Send Emails with Python?</a></p> <p> Feel free to <strong>let us</strong> know what content would be useful for you!</p> </body> </html> """

# 将两个部分都转换为MIMEText对象,并将它们添加到MIMEMultipart消息中 
part1 = MIMEText(text, "plain") 
part2 = MIMEText(html, "html") 
# message.attach(part1)
message.attach(part2)

# 使用smtplib.SMTP("smtp.yourserver.com",25)作为服务器发送电子邮件:server.login(登录名和密码)
with smtplib.SMTP(smtp_server, port) as server:
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string()) 
    print('Sent')




添加附件如PDF文件的示例


import smtplib
# 导入对应的模块
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定主题、发件人和收件人的电子邮件地址
subject = "An example of boarding pass"
sender_email = "jk.d@aisino.sh.cn" 
receiver_email = "2818686037@qq.com"

message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# 将正文添加到电子邮件
body = "This is an example of how you can send a boarding pass in attachment with Python"
message.attach(MIMEText(body, "plain"))
# 添加任意类型(pdf、word、excel、jpg等)的附件
filename = "Ansible From Beginner to Pro.pdf"

# 以二进制模式打开PDF文件
# 我们假设该PDF文件位于您从中运行Python脚本的目录中
with open(filename, "rb") as attachment:
    # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

    # base64编码
    encoders.encode_base64(part)

    # 添加标题 
    part.add_header(
        "Content-Disposition",
        f"attachment; filename= {filename}",
    )

    # 在邮件中添加附件并将其转换为字符串
    message.attach(part)
    text = message.as_string()

    # 发送您的电子邮件
    with smtplib.SMTP(smtp_server, port) as server:
        server.login(login, password)
        server.sendmail(sender_email, receiver_email, text)
    print('Sent')



发送多个附件


import smtplib
# 导入对应的模块
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定主题、发件人和收件人的电子邮件地址
subject = "An example of boarding pass"
sender_email = "jk.d@aisino.sh.cn" 
receiver_email = "2818686037@qq.com"

message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# 将正文添加到电子邮件
body = "This is an example of how you can send a boarding pass in attachment with Python"
message.attach(MIMEText(body, "plain"))
# 添加任意类型(pdf、word、excel、jpg等)的附件存放入列表
list = ["Ansible From Beginner to Pro.pdf","currency.xlsx"]
for filename in list:
    # 以二进制模式打开附件
    # 我们假设该附件位于您从中运行Python脚本的目录中
    with open(filename, "rb") as attachment:
        # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
        part = MIMEBase("application", "octet-stream")
        part.set_payload(attachment.read())

        # base64编码
        encoders.encode_base64(part)

        # 添加标题 
        part.add_header(
            "Content-Disposition",
            f"attachment; filename= {filename}",
        )

        # 在邮件中添加附件并将其转换为字符串
        message.attach(part)
        text = message.as_string()

# 发送您的电子邮件
with smtplib.SMTP(smtp_server, port) as server:
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, text)
print('Sent')


发送嵌入图片

在电子邮件消息中包含图像的三种常见方法是:base64图像(嵌入式嵌入),CID附件(作为MIME对象嵌入)和链接的图像

# 首先导入需要的库
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import base64


smtp_server = "smtp.aisino.sh.cn"
port = 25

# 邮箱账号和密码
login = "jk.d@aisino.sh.cn"
password = "xxx"

# 指定主题、发件人和收件人的电子邮件地址
subject = "inline embedding"
sender_email = "jk.d@aisino.sh.cn"
receiver_email = "2818686037@qq.com"

message = MIMEMultipart("alternative")
message["Subject"] = subject
message["From"] = sender_email
message["To"] = receiver_email

# 样本图像文件与您从中运行Python脚本的目录相同
encoded = base64.b64encode(open("example.jpg", "rb").read()).decode()
html = f"""\
<html>
 <body>
   <img src="data:image/jpg;base64,{encoded}">
 </body>
</html>
"""

part = MIMEText(html, "html")
message.attach(part)

# 发送您的电子邮件
with smtplib.SMTP(smtp_server, port) as server:
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())
print('Sent')




发邮件给多人并带附件


import smtplib,csv
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders


smtp_host = "smtp.aisino.sh.cn"
port = 25
# 邮箱账号和密码
MY_ADDRESS = 'jk.d@aisino.sh.cn'
PASSWORD = 'xxx'
# 邮件主题
SUBJECT = "Order confirmation33"

def get_contacts(filename):
    """
    返回两个列表名称:names 和 emails
    从文件名指定的文件中读取
    """
    
    names = []
    emails = []
    with open(filename, mode='r', encoding='utf-8') as contacts_file:
        reader = csv.reader(contacts_file)
        # 跳过标题行
        next(reader)
        for name, email in reader:
            names.append(name)
            emails.append(email)
    return names, emails


def read_template(filename):
    """
    返回包含以下内容的Template对象
    文件名指定的文件
    """
    
    with open(filename, 'r', encoding='utf-8') as template_file:
        template_file_content = template_file.read()
    return Template(template_file_content)


def add_attachment(filelist):
    """
    返回一个附件列表 parts
    """
    
    parts = []
    message = MIMEMultipart()
    for filename in filelist:
        # 附件位于该Python脚本的目录中
        # 以二进制模式打开附件
        with open(filename, "rb") as attachment:
            # 内容类型“应用程序/八位字节流”表示MIME附件是二进制文件
            part = MIMEBase("application", "octet-stream")
            part.set_payload(attachment.read())
            # base64编码
            encoders.encode_base64(part)
            # 添加标题 
            part.add_header(
                "Content-Disposition",
                f"attachment; filename= {filename}",
            )
            parts.append(part)
    return parts


def main():
    # 读取联系人、邮件模板、附件
    names, emails = get_contacts('contacts.csv')
    message_template = read_template('mail_template.txt')
    # 添加任意类型(pdf、word、excel、jpg等)的附件存放入列表
    list_attachment = ["Ansible From Beginner to Pro.pdf", "currency.xlsx"]
    parts = add_attachment(list_attachment)
    # 设置SMTP服务器
    with smtplib.SMTP(smtp_host, port) as smtp_server:
        smtp_server.login(MY_ADDRESS, PASSWORD)
        # 为每个联系人发送电子邮件
        for name, email in zip(names, emails):
            # 创建一条message
            message = MIMEMultipart()
            # 将实际的人名添加到消息模板中
            msg = 'Hi ' + name + message_template.substitute(PERSON_NAME=name.title())
            # 打印出邮件正文
            print(msg)
            # 设置message的参数:发件人、收件人、抄送、主题
            message['From'] = MY_ADDRESS
            message['To'] = email
            message['Cc'] = '2818686037@qq.com'
            message['Subject'] = SUBJECT          
            # 添加message正文
            message.attach(MIMEText(msg, 'plain'))            
            # 在邮件中添加附件并将其转换为字符串
            for part in parts:
                message.attach(part)
                text = message.as_string()
            # 通过先前设置的服务器发送邮件
            smtp_server.sendmail(MY_ADDRESS, email, text)
            # 不用text的话,也可以这样发邮件smtp_server.send_message(message)
            print(f'\nEmail successfully sent to {name}!')
            print('-'*100)

    
if __name__ == '__main__':
    main()





评论

此博客中的热门博文

学习地址

清华大学计算机系课程攻略 https://github.com/PKUanonym/REKCARC-TSC-UHT 浙江大学课程攻略共享计划 https://github.com/QSCTech/zju-icicles https://home.unicode.org/ 世界上的每个人都应该能够在手机和电脑上使用自己的语言。 http://codecanyon.net   初次看到这个网站,小伙伴们表示都惊呆了。原来代码也可以放在网上卖的?!! 很多coder上传了各种代码,每个代码都明码标价。看了下销售排行,有的19刀的卖了3万多份,额di神啊。可以看到代码的演示效果,真的很漂亮。代码以php、wordpress主题、Javascript、css为主,偏前台。 https://www.lintcode.com/ 算法学习网站,上去每天刷两道算法题,走遍天下都不怕。 https://www.codecademy.com/ 包含在线编程练习和课程视频 https://www.reddit.com/ 包含有趣的编程挑战题,即使不会写,也可以查看他人的解决方法。 https://ideone.com/ 在线编译器,可运行,可查看代码示例。 http://it-ebooks.info/ 大型电子图书馆,可即时免费下载书籍。 刷题 https://github.com/jackfrued/Python-100-Days https://github.com/kenwoodjw/python_interview_question 面试问题 https://github.com/kenwoodjw/python_interview_question https://www.journaldev.com/15490/python-interview-questions#python-interpreter HTTP 身份验证 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Authentication RESTful 架构详解 https://www.runoob.com/w3cnote/restful-architecture.html https://www.rosettacode.org/wiki/Rosetta_C...

PDF处理

虚拟pdf打印机 pdfFactory  https://fineprint.com PDFCreator  https://www.pdfforge.org 开源 cutepdf https://www.cutepdf.com/index.htm Doro PDF Writer http://www.the-sz.com/products/doro PdfScribe  https://github.com/stchan/PdfScribe/releases pdf阅读器 Sumatra PDF https://www.sumatrapdfreader.org/ 为什么 Python 用于 PDF 处理  如您所知,PDF 处理属于文本分析。 大多数文本分析库或框架仅使用 Python 设计。 这为文本分析提供了优势。 还有一件事,您永远无法在现有的机器学习或自然语言处理框架中直接处理 pdf。 除非他们为此证明了显式接口。 我们必须先将pdf转换为文本。 我们可以使用下述任何库轻松实现这一点。 在线转换pdf Sejda https://www.sejda.com/pdf-editor 每个文档 200 页的免费限制 https://www.pdf2go.com/ https://tools.pdfforge.org/extract-text PDF24 Tools https://tools.pdf24.org/zh/ 免费且易于使用的在线PDF工具 FreeOCR http://www.paperfile.net/ 适用于Windows的免费光学字符识别软件,支持大多数Twain扫描仪的扫描,还可以打开大多数扫描的PDF和多页Tiff图像以及流行的图像文件格式,FreeOCR输出纯文本,可以直接导出为Microsoft Word格式。 不支持中文 wkhtmltopdf 和 wkhtmltoimage 是使用 QT Webkit 渲染引擎将 HTML 渲染为 PDF 和各种图像格式的命令行工具。这些完全“无头”运行,不需要显示或显示服务。 https://wkhtmltopdf.org/ django-wkhtmltopdf 允许 Django 站点输出动态 PDF。它利用 wkhtmltopdf 库,允许您使用您知道...

安卓 之 apk下载、ADB、 scrcpy

Apk下载 下载离线安装apk https://www.apkmirror.com/ 免费和安全的Android APK下载 https://apkpure.com/ 被暴雷,有植入 https://apps.evozi.com/apk-downloader/ 可以将Google Play( https://play.google.com )中的apk文件所在网址直接下载到台式机和设备上 https://f-droid.org/zh_Hans/ F-Droid 是一个 Android 平台上 FOSS(Free and Open Source Software,自由开源软件)的目录,并提供下载安装支持。使用客户端可以更轻松地浏览、安装及跟进设备上的应用更新。 https://gitlab.com/AuroraOSS/AuroraStore Aurora商店 是Google Play商店的非官方FOSS客户,设计典雅。 Aurora商店不仅下载,更新和搜索Play商店等应用 https://github.com/OpenTracksApp/OpenTracks OpenTracks是一款运动跟踪应用程序,完全尊重您的隐私。 Tasker https://tasker.joaoapps.com/ 是一款适用于Android的应用程序,它可以根据用户定义的配置文件中的上下文、可点击或定时的主屏幕小部件来执行任务。它无需root或特殊的主屏幕就能控制Android设备。 AsciiCam AsciiCam可以从您的相机指向的任何位置实时生成ASCII图像。选择黑白,原色或全彩,拍照,并将其作为图像或HTML共享。您还可以在库中创建ASCII版本的图片,并且每次使用标准相机应用程序拍摄照片时,也可以选择自动生成ASCII版本。 AsciiCam是完全免费和开源的。 Apk1安装器 优化微信apk文件接收体验。 微信收到apk文件会加 ".1" 后缀导致打不开,必须自己手动找到文件重命名去掉后缀。 使用本安装器就可以在微信内,潇洒地点击直接打开。甚至可以在安装器内浏览apk1文件历史接收记录。 ADB ADB全名是 Android Debug Bridge,是开发或使用Android时很常用的工具。可以从电脑通过USB连线到Android手机上 https:...