1. 程式人生 > >python 自動傳送郵件傳送多人、群發、多附件

python 自動傳送郵件傳送多人、群發、多附件

1、最近公司實現部分資料統計、分析的報表進行每天定時傳送到相關人員的郵箱之中的配置程式碼被人為刪除了,需要重新恢復該功能,由於原先是在linux上使用shell配置傳送,實在是太繁瑣,所以準備使用python來實現該功能,不過發現網上各種文件都是未經過整理,程式碼寫的很不友善,比如傳送多人的只能傳送前一個郵箱,附件寫死不靈活等等,故特寫一遍比較記錄。

主要會遇到的幾個問題:

1、smtplib.SMTPAuthenticationError: (550, b'User has no permission')

2、smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed')

這兩個錯誤是你的密碼用的不是授權碼導致,授權碼生成自行百度。

3、554 DT:SPM 163 smtp5

這屬於網易郵箱的一個退回檢測機制導致,貌似跟傳送比較頻繁有關,我再發送的時候有遇到過,直到添加了一個網易郵箱作為收件箱之後才能傳送成功,不知道是不是這個原因導致,具體原因未知,如果有人知道請在私信或者評論下告知,謝謝!!

前期準備檢視系統上python版本號:


顯示如圖表示已經安裝好了。

2、實現程式碼如下(這是在Windows上的IDEL下編輯測試程式碼,linux上只有改下附件路徑就好了)

# -*- coding: utf-8 -*-
from email import encoders
import os
import traceback
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders


# 中文處理
def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))

def send_email(to_addr_in,filepath_in):
    # 郵件傳送和接收人配置
    from_addr = '*******@163.com'
    smtp_server = 'smtp.163.com'
    password = '********'  #這是你郵箱的第三方授權客戶端密碼,並非你的登入密碼
    to_addr = to_addr_in
    to_addrs = to_addr.split(',')

    msg = MIMEMultipart()
    msg['From'] = _format_addr('Python愛好者 <%s>' % from_addr)        # 顯示的發件人
    # msg['To'] = _format_addr('管理員 <%s>' % to_addr)                # 單個顯示的收件人
    msg['To'] = ",".join(to_addrs)                                    # 多個顯示的收件人
    msg['Subject'] = Header('來自SMTP的問候……', 'utf-8').encode()      # 顯示的郵件標題

    # 需要傳入的路徑
    # filepath = r'D:\test'
    filepath = filepath_in
    r = os.path.exists(filepath)
    if r is False:
        msg.attach(MIMEText('no file...', 'plain', 'utf-8'))
    else:
        # 郵件正文是MIMEText:
        msg.attach(MIMEText('send with file...', 'plain', 'utf-8'))
        # 遍歷指定目錄,顯示目錄下的所有檔名
        pathDir = os.listdir(filepath)
        for allDir in pathDir:
            child = os.path.join(filepath, allDir)
            print child.decode('gbk')  # .decode('gbk')是解決中文顯示亂碼問題

            # 新增附件就是加上一個MIMEBase,從本地讀取一個檔案
            with open(child, 'rb') as f:
                # 設定附件的MIME和檔名,這裡是txt型別:
                mime = MIMEBase('file', 'xls', filename=allDir)
                # 加上必要的頭資訊:
                mime.add_header('Content-Disposition', 'attachment', filename=allDir)
                mime.add_header('Content-ID', '<0>')
                mime.add_header('X-Attachment-Id', '0')
                # 把附件的內容讀進來:
                mime.set_payload(f.read())
                # 用Base64編碼:
                encoders.encode_base64(mime)
                # 新增到MIMEMultipart:
                msg.attach(mime)
    try:
        server = smtplib.SMTP(smtp_server, 25)
        # server.starttls()
        server.set_debuglevel(1)  # 用於顯示郵件傳送的執行步驟
        server.login(from_addr, password)
        # print to_addrs
        server.sendmail(from_addr, to_addrs, msg.as_string())
        server.quit()
    except Exception, e:
        print "Error: unable to send email"
        print traceback.format_exc()

if __name__ == '__main__':
    send_email('*******@qq.com,*******@163.com','D:\\test')


3、在 PyCharm 裡面執行結果如下

顯示郵件已經發送成功了,可在相應的郵箱裡面檢視,相應的資料夾下存在附件文字


如果不存在附件文字(這是截圖的網易郵箱,上面截圖的是QQ郵箱表示兩個郵箱都已經收到郵件):