Python study notes (1) - using SMPT to automatically send mail scripts

origin

The school happened to organize a summer camp, and the students who participated in the summer camp needed to be notified by email. The registration information included the mobile phone number and email (for operating expenses, I gave up my mobile phone). Then, a small partner proposed a way for python to send emails. After referring to several blogs, I came up with this article.

Involved content

Python reads txt text
Reference link: https://blog.csdn.net/qq_37828488/article/details/100024924

Python uses openpyxl to read Excel tables
Reference link: https://blog.csdn.net/weixin_43094965/article/details/82226263

Python uses the built-in SMTP module

principle

SMTP is a relatively simple text-based protocol. On which one or more recipients of a message are specified (in most cases confirmed to exist), and the message text is transmitted. An SMTP server can be tested very simply through the telnet program. SMTP uses TCP port 25. To determine an SMTP server for a given domain name, MX (Mail eXchange) DNS is used. (Excerpt from - SMTP Baidu Encyclopedia https://baike.baidu.com/item/SMTP/175887?fr=aladdin )

Python built-in SMTP module

Python has built-in support for SMTP, which can send plain text emails, HTML emails, and emails with attachments

Reference link 1: https://www.liaoxuefeng.com/wiki/897692888725344/923057144964288
Reference link 2:
https://www.runoob.com/python/python-email.html

The syntax for creating an SMTP object in python is as follows:

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
smtpObj.connect(smtpserver,25) #(缺省)默认端口是25 也可以根据服务器进行设定
smtpObj.login(user,password) #登陆smtp服务器

Parameter Description:

  • host: SMTP server host. You can specify the host's ip address or domain name such as: runoob.com, this is an optional parameter.
  • port: If you provide the host parameter, you need to specify the port number used by the SMTP service. Normally, the SMTP port number is 25.
  • local_hostname: If SMTP is on your local machine, you only need to specify the server address as localhost.
  • smtserver SMPT server address of sender's mailbox
  • user, password is the sender's email address and password

The Python SMTP object uses the sendmail method to send mail, the syntax is as follows:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

Parameter Description:

  • from_addr: Email sender address.
  • to_addrs: list of strings, addresses to send emails to.
  • msg: Send a message, essentially a MIMEText object
  • Here we should pay attention to the third parameter, msg is a string, which means mail. We know that emails are generally composed of title, sender, recipient, email content, attachments, etc. When sending emails, pay attention to the format of msg. This format is the format defined in the smtp protocol.

The syntax of a MIMEText object is as follows:

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

 msg = MIMEText('您好,巴拉巴拉巴拉!', 'plain', 'utf-8') #创建纯文本内容
 msg['From'] = Header('LuH1124的CSDN博客','utf-8')
 msg['To'] = Header('张三','utf-8')
 subject = '小小的 SMTP 测试邮件'
 msg['Subject'] = Header(subject, 'utf-8')

Parameter Description:

  • The second parameter in the fifth line is the subtype of MIME, pass in 'plain', the final MIME is 'text/plain', and finally must use utf-8 encoding to ensure multi-language compatibility.
  • The sixth line is the sender's name
  • The seventh line is the name of the recipient
  • The eighth and ninth lines are the subject of the email

SMPT send mail process

The basic process of SMTP communication can be summarized as follows:

1. Connect to the SMTP server

2. Login username and password

3. Send the specified email content

4. Quit the SMTP connection

The procedure for sending plain text references is as follows:

# coding:utf-8
import importlib
import sys
importlib.reload(sys)
sys.setdefaultencoding('utf8')
import smtplib
from smtplib import SMTP
from email.mime.text import MIMEText
from email.header import Header
 
#构造纯文本邮件内容
msg = MIMEText('您好,巴拉巴拉巴拉!','plain','utf-8')
msg['From'] = Header('LuH1124的CSDN博客','utf-8')
msg['To'] = Header('张三','utf-8')
subject = '小小的 SMTP 测试邮件'
msg['Subject'] = Header(subject, 'utf-8')
#发送者邮箱
sender = '[email protected]'
 
#发送者的登陆用户名和密码
user = '[email protected]'
password = 'xxxxxx'
 
#发送者邮箱的SMTP服务器地址 比如 SMTP.163.com
smtpserver = 'xxxx'
 
#接收者的邮箱地址
receiver = ['[email protected]','[email protected]'] #receiver 可以是一个list
 
smtp = smtplib.SMTP() #实例化SMTP对象
smtp.connect(smtpserver,25) #(缺省)默认端口是25 也可以根据服务器进行设定
smtp.login(user,password) #登陆smtp服务器
smtp.sendmail(sender,receiver,msg.as_string()) #发送邮件 
smtp.quit() # 退出SMTP服务器

The test results are as follows:
insert image description here

The reference procedure for sending attachments is as follows:

To send an email with attachments, you must first create a MIMEMultipart() instance, and then construct the attachments. If there are multiple attachments, you can construct them one by one, and finally use smtplib.smtp to send them.

# -*- coding: UTF-8 -*-
 
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
 
sender ='[email protected]'
receivers = ['[email protected]']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
 
#发送者的登陆用户名和密码
user = '[email protected]'
password = 'buzhiDAO99'

#发送者邮箱的SMTP服务器地址 比如 SMTP.163.com
smtpserver = 'smtp.buaa.edu.cn'

#创建一个带附件的实例
msg = MIMEMultipart()
msg['From'] = Header('LuH1124的CSDN博客','utf-8')
msg['To'] = Header('张三','utf-8')
subject = '带附件的 SMTP 测试邮件'
msg['Subject'] = Header(subject, 'utf-8')
 
#邮件正文内容
msg.attach(MIMEText('附件发送测试……', 'plain', 'utf-8'))
 
# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.png', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.png"'
msg.attach(att1)
 
# 构造附件2,传送当前目录下的 runoob.txt 文件
att2 = MIMEText(open('email.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="email.txt"'
msg.attach(att2)
 
try:
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver,25) #(缺省)默认端口是25 也可以根据服务器进行设定
    smtp.login(user,password) #登陆smtp服务器
    smtp.sendmail(sender, receivers, msg.as_string())
    print("邮件发送成功")
    smtp.quit() # 退出SMTP服务器
except smtplib.SMTPException:
    print("Error: 无法发送邮件")

The test results are as follows:
insert image description here

Read mailbox information saved in txt and Excel

The above is the operation of sending emails automatically. Next, let’s talk about the program of reading mailbox information from txt and Excel, adding it to the body of the email, and modifying the recipient list.

  1. The first is to read the txt text to achieve group sending. For the convenience of operation, the content of the txt text is shown in the figure:
    insert image description here

In the txt text, copying the mailbox column directly from excel is the above format. The main function used is readlines(), see the reference link at the beginning of the article. There is a newline character "\n" between each mailbox string, you need to use the str.split() method of the string.
Define the function as follows:

def read_txt(path):
    email_list =[]
    with open(path, "r") as file:
        for line in file.readlines():
            #ine = line.strip('\n')
            email_list.append(line)
        return email_list

The return value of the function can be used as the value of the receiver list and brought into the program. The path parameter refers to the path and file name of the file.

  1. The second is to read the Excel text. The content format of the Excel text is as shown in the figure:
    insert image description here
    In this text, we want to realize the extraction of the name (you can add the name of the classmate in the body of the mailbox) and the mailbox, and save them in name_list and email_list.
import openpyxl
wb = openpyxl.load_workbook("Chat_Sum.xlsx")
ws = wb.active # 获取sheet1
name_range = ws['B2':'B' + str(ws.max_row)]
email_range = ws['E2':'E' + str(ws.max_row)]
#print(ws.max_row)
#print(ws.max_column)
name_list = []
email_list = []
#name_range
for name in name_range:
    name_list.append(name[0].value)
for email in email_range:
    email_list.append(email[0].value)

Introduce the openpyxl module, use load_workbook to read excel, use active to read sheet1, use max_row to read the number of table rows, select B2 column and E2 column data, save them in name_range and email_range after reading, and the data structure is a tuple list , the index [0] is read.

The last program can achieve single posting and group posting, and change the name of the text

# coding:utf-8
import importlib
import sys
importlib.reload(sys)

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

import openpyxl


def read_xlsx(path):
    wb = openpyxl.load_workbook(path)
    ws = wb.active # 获取sheet1
    name_range = ws['B2':'B' + str(ws.max_row)]
    email_range = ws['E2':'E' + str(ws.max_row)]
    #print(ws.max_row)
    #print(ws.max_column)
    name_list = []
    email_list = []
    #name_range
    for name in name_range:
        name_list.append(name[0].value)
    for email in email_range:
        email_list.append(email[0].value)
    return name_list,email_list

def read_txt(path):
    email_list =[]
    with open(path, "r") as file:
        for line in file.readlines():
            #ine = line.strip('\n')
            email_list.append(line)
        return email_list
    
def init_Smpt(smtpserver,user,password ):
    smtp = smtplib.SMTP()  # 实例化SMTP对象
    smtp.connect(smtpserver, 25)  # (缺省)默认端口是25 也可以根据服务器进行设定
    smtp.login(user, password)  # 登陆smtp服务器,login()方法用来登录SMTP服务器
    return smtp

def send_Mass_Smpt(sender, receiver_list, msg): # 群发相同内容
    smtp.sendmail(sender,receiver_list, msg.as_string())  # 发送邮件 ,这里有三个参数
    '''
    sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文
    是一个str,as_string()把MIMEText对象变成str。
    '''
    smtp.quit()

def send_Alone_Smpt(sender, receiver_list, msg): # 单发不同同内容
    smtp.sendmail(sender,receiver_list, msg.as_string())  # 发送邮件 ,这里有三个参数
    '''
    sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文
    是一个str,as_string()把MIMEText对象变成str。
    '''
    smtp.quit()

if __name__ == '__main__':
    
    # 文件地址
    txt_path = "./email.txt"
    xlsx_path = "./Chat_Sum.xlsx"
    
    # 接收者的姓名和邮箱地址
    receiver_name_list, receiver_list = read_xlsx(xlsx_path) # receiver 可以是一个list
    flag = False 
    '''
    **群发标志位 True:可读取 txt 和 xlsx文件
              False:只可读取 xlsx文件**
    ''' 
    
    # 发送者邮箱
    sender = '[email protected]'

    # 发送者的登陆用户名和密码
    user = '[email protected]'
    password = '*******' # 密码需要修改成自己的

    # 发送者邮箱的SMTP服务器地址
    smtpserver = 'smtp.163.com'
    
    if flag:
        # 群发
        # 构建邮件邮件内容
        smtp = init_Smpt(smtpserver,user,password)
        msg = MIMEText('您好,欢迎~~~~~!', 'plain', 'utf-8')
        # 构造纯文本邮件内容,第12行是发送人,第3行是收件人,第4行是邮件标题
        msg['From'] = Header('CSDnTEST','utf-8')
        msg['To'] = Header('张三','utf-8')
        subject = ' SMTP 测试邮件'
        msg['Subject'] = Header(subject, 'utf-8')
        send_Mass_Smpt(sender, receiver_list, msg)
    else: 
        # 单发
        # 构建邮件邮件内容,
        for index in range(len(receiver_name_list)): 
            smtp = init_Smpt(smtpserver,user,password) # 需重新初始化邮箱
            msg = MIMEText('{}您好,欢迎参加~~~~夏令营!'.format(receiver_name_list[index]), 'plain', 'utf-8') #format 格式化输出姓名
            # 构造纯文本邮件内容,第12行是发送人,第3行是收件人,第4行是邮件标题
            msg['From'] = Header('CSDNtest','utf-8')
            msg['To'] = Header('张三','utf-8')
            subject = 'SMTP 测试邮件'
            msg['Subject'] = Header(subject, 'utf-8')
            send_Alone_Smpt(sender, receiver_list[index], msg)

Guess you like

Origin blog.csdn.net/weixin_43357695/article/details/107424865