基于Python實現(xiàn)一鍵群發(fā)郵件并自動收發(fā)附件功能
引入:郵件操作重復又耗時?你的溝通效率正在“掉鏈子”!
郵件操作重復又耗時?你的溝通效率正在“掉鏈子”!
在職場中,郵件是主要的溝通工具。但你有沒有被它“拖垮”過效率?
每月需要向幾百個客戶郵件群發(fā)促銷信息,手動一封封發(fā)送,或者復制粘貼修改內(nèi)容,耗時巨大。
需要定期發(fā)送提醒或通知,卻總是忘記定時郵件,導致工作延誤。
這些重復、低效的郵件操作,不僅消耗你的精力,更影響你的溝通效率和辦公自動化進程
我將帶你進入郵件自動化的奇妙世界!我們將手把手教你如何利用Python的smtplib和imaplib/poplib庫,輕松實現(xiàn):
Python發(fā)送郵件: 批量發(fā)送、定制內(nèi)容、附件自動發(fā)送。
Python接收郵件: 自動讀取、篩選,并智能下載附件。
最終,你將擁有一個強大的**“智能郵件管家”**,
1.使用 smtplib庫,完成你的自動化郵件!
要實現(xiàn)Python發(fā)送郵件,我們主要使用Python內(nèi)置的smtplib庫。SMTP是用于發(fā)送電子郵件的標準協(xié)議,smtplib就是Python對SMTP客戶端的實現(xiàn)。
實現(xiàn): smtplib通過連接到SMTP服務(wù)器,模擬郵件客戶端的行為,將郵件發(fā)送出去。
1.1 準備:SMTP服務(wù)器配置與授權(quán)碼獲取
在編寫代碼之前,你需要獲取一些信息:
SMTP服務(wù)器地址: 不同的郵箱服務(wù)商有不同的SMTP地址。
SMTP端口: 通常是25、465(SSL加密)或587(TLS加密)。
發(fā)件人郵箱和密碼(或授權(quán)碼): 強烈建議使用授權(quán)碼而不是郵箱密碼,授權(quán)碼是專門為第三方客戶端登錄生成的專用密碼,安全性更高。
[表格:常見郵箱服務(wù)商SMTP配置]
| 服務(wù)商 | SMTP服務(wù)器地址 | 端口(SSL/TLS) | 備注 |
|---|---|---|---|
| QQ郵箱 | smtp.qq.com | 465(SSL)/587(TLS) | 需要開啟SMTP服務(wù)并獲取授權(quán)碼 |
| 163郵箱 | smtp.163.com | 465(SSL)/994(SSL) | 需要開啟SMTP服務(wù)并獲取授權(quán)碼 |
| Gmail | smtp.gmail.com | 465(SSL)/587(TLS) | 可能需要開啟“兩步驗證”并生成應(yīng)用專用密碼 |
| Outlook | smtp.office365.com | 587(TLS) |
如何獲取授權(quán)碼(以QQ郵箱為例):
登錄QQ郵箱網(wǎng)頁版。
進入“設(shè)置” -> “賬戶”。
找到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務(wù)”,點擊“開啟”或“生成授權(quán)碼”。


根據(jù)提示完成驗證,即可獲得授權(quán)碼。
1.2 發(fā)送你的第一封自動化郵件:文字內(nèi)容與標題
用Python發(fā)送一封簡單的文本郵件。
代碼:
import smtplib
from email.mime.text import MIMEText # 用于構(gòu)建文本郵件
from email.header import Header # 用于處理郵件標題中的中文
def send_simple_email(sender_email, sender_password, receiver_email, subject, content):
"""
發(fā)送一封簡單的文本郵件。
這是Python發(fā)送郵件的基礎(chǔ)。
:param sender_email: 發(fā)件人郵箱地址
:param sender_password: 發(fā)件人郵箱授權(quán)碼或密碼
:param receiver_email: 收件人郵箱地址
:param subject: 郵件主題
:param content: 郵件正文
"""
# 郵件內(nèi)容對象:MIMEText用于純文本郵件,'plain'表示純文本
message = MIMEText(content, 'plain', 'utf-8')
message['From'] = Header(f"Python自動化助手 <{sender_email}>", 'utf-8') # 設(shè)置發(fā)件人顯示名稱
message['To'] = Header(f"收件人 <{receiver_email}>", 'utf-8') # 設(shè)置收件人顯示名稱
message['Subject'] = Header(subject, 'utf-8') # 設(shè)置郵件主題
try:
# 連接到SMTP服務(wù)器(這里以QQ郵箱為例,使用SSL加密)
smtp_server = "smtp.qq.com"
smtp_port = 465 # SSL端口
# 使用with語句確保SMTP連接被正確關(guān)閉
with smtplib.SMTP_SSL(smtp_server, smtp_port) as smtp_obj: # SMTP_SSL用于SSL加密連接
smtp_obj.login(sender_email, sender_password) # 登錄郵箱
smtp_obj.sendmail(sender_email, receiver_email, message.as_string()) # 發(fā)送郵件
print(f"? 郵件已成功發(fā)送到:{receiver_email}")
except Exception as e:
print(f"? 郵件發(fā)送失敗:{e}")
print("請檢查發(fā)件人郵箱、授權(quán)碼、收件人地址和SMTP服務(wù)器配置。")
if __name__ == "__main__":
# --- 請?zhí)鎿Q為你的實際郵箱信息和收件人 ---
my_email = "你的QQ郵箱@qq.com" # 例如: 123456789@qq.com
my_password = "你的郵箱授權(quán)碼" # **非常重要,不要用郵箱登錄密碼!**
target_email = "目標郵箱@example.com" # 例如: test_receiver@example.com
send_simple_email(my_email, my_password, target_email,
"來自Python自動化測試郵件",
"這是一封由Python腳本自動發(fā)送的測試郵件。\n你好,世界!")
步驟:
獲取授權(quán)碼: 參照1.1節(jié)獲取你的郵箱授權(quán)碼。
修改代碼信息: 復制上方代碼到VS Code,保存為
send_simple_email.py。修改 my_email、my_password、target_email 等。
運行: 在VS Code終端運行 python send_simple_email.py。
檢查: 檢查目標郵箱是否收到郵件。
展示:

1.3 發(fā)送你的第一封自動化郵件:文字內(nèi)容與標題
場景: 你需要向客戶發(fā)送包含PDF報告、Excel數(shù)據(jù)或圖片等附件的郵件,或者發(fā)送帶有圖文并茂的HTML格式郵件內(nèi)容。
方案: email.mime.multipart 和 email.mime.application 模塊能幫你構(gòu)建復雜郵件,包括多部分內(nèi)容和各種類型附件,實現(xiàn)郵件附件處理的自動化。
代碼:
import smtplib
from email.mime.multipart import MIMEMultipart # 用于構(gòu)建多部分郵件
from email.mime.text import MIMEText
from email.mime.base import MIMEBase # 用于附件
from email import encoders # 用于附件編碼
from email.header import Header
import os
def send_email_with_attachment_and_html(sender_email, sender_password, receiver_email, subject, html_content, attachment_path=None):
"""
發(fā)送帶附件和HTML內(nèi)容的郵件。
這是Python發(fā)送郵件的高級功能,實現(xiàn)郵件群發(fā)和郵件附件處理。
:param sender_email: 發(fā)件人郵箱地址
:param sender_password: 發(fā)件人郵箱授權(quán)碼或密碼
:param receiver_email: 收件人郵箱地址
:param subject: 郵件主題
:param html_content: 郵件正文 (HTML格式)
:param attachment_path: 附件文件路徑,可選
"""
# 創(chuàng)建多部分郵件對象 (用于包含文本和附件)
msg = MIMEMultipart('mixed') # 'mixed' 表示郵件包含不同類型的部分
msg['From'] = Header(f"Python智能助手 <{sender_email}>", 'utf-8')
msg['To'] = Header(f"重要收件人 <{receiver_email}>", 'utf-8')
msg['Subject'] = Header(subject, 'utf-8')
# 1. 添加HTML內(nèi)容 (Part 1: HTML Body)
html_part = MIMEText(html_content, 'html', 'utf-8') # 'html'表示HTML格式
msg.attach(html_part) # 將HTML部分添加到郵件
# 2. 添加附件 (Part 2: Attachment)
if attachment_path and os.path.exists(attachment_path):
try:
with open(attachment_path, 'rb') as fp:
# MIMEBase用于所有非文本附件
attachment = MIMEBase('application', 'octet-stream')
attachment.set_payload(fp.read()) # 讀取附件內(nèi)容
encoders.encode_base64(attachment) # 編碼附件內(nèi)容
# 設(shè)置附件文件名,確保中文文件名正常顯示
attachment.add_header('Content-Disposition', 'attachment',
filename=Header(os.path.basename(attachment_path), 'utf-8').encode())
msg.attach(attachment) # 將附件添加到郵件
print(f" ? 附件 '{os.path.basename(attachment_path)}' 已添加。")
except Exception as e:
print(f"? 添加附件失?。簕e}")
else:
print(" ?? 未添加附件或附件文件不存在。")
try:
smtp_server = "smtp.qq.com"
smtp_port = 465 # SSL端口
with smtplib.SMTP_SSL(smtp_server, smtp_port) as smtp_obj:
smtp_obj.login(sender_email, sender_password)
smtp_obj.sendmail(sender_email, receiver_email, msg.as_string())
print(f"? 郵件 (含附件/HTML) 已成功發(fā)送到:{receiver_email}")
except Exception as e:
print(f"? 郵件發(fā)送失敗:{e}")
print("請檢查發(fā)件人郵箱、授權(quán)碼、收件人地址和SMTP服務(wù)器配置。")
if __name__ == "__main__":
# --- 請?zhí)鎿Q為你的實際郵箱信息和收件人 ---
my_email = "你的QQ郵箱@qq.com"
my_password = "你的郵箱授權(quán)碼"
target_email = "目標郵箱@example.com"
# HTML郵件內(nèi)容
html_body = """
<html>
<body>
<p>尊敬的客戶:</p>
<p>您好!</p>
<p>這是您的<b>最新銷售報告</b>,請查收附件。</p>
<p>感謝您的支持!</p>
<img src="https://via.placeholder.com/150" alt="占位符圖片">
<p>Python自動化團隊 敬上</p>
</body>
</html>
"""
# 附件文件 (準備一個測試PDF或圖片文件)
test_attachment_path = os.path.expanduser("~/Desktop/test_report.pdf")
if not os.path.exists(test_attachment_path):
# 簡單創(chuàng)建模擬PDF附件
import fitz; doc=fitz.open(); doc.new_page().insert_text((50,50),"附件內(nèi)容"); doc.save(test_attachment_path); doc.close()
print(f"臨時附件文件 '{os.path.basename(test_attachment_path)}' 已創(chuàng)建。")
send_email_with_attachment_and_html(my_email, my_password, target_email,
"【Python自動化】2023年度銷售報告",
html_body,
test_attachment_path)
步驟:
獲取授權(quán)碼: 參照1.1節(jié)獲取你的郵箱授權(quán)碼。
準備附件: 在桌面創(chuàng)建一個test_report.pdf文件(或任何其他文件)。
修改代碼信息: 修改 my_email、my_password、target_email、test_attachment_path 等。
運行: 運行 python send_email_attachment_html.py。
檢查: 檢查目標郵箱是否收到帶附件和HTML內(nèi)容的郵件。
效果展示:

2. 郵件接收核心:Python imaplib / poplib庫,完成自動化收件
發(fā)送郵件只是自動化的一半。要實現(xiàn)真正的郵件自動化和自動收發(fā)附件,自動登錄郵箱,讀取郵件,甚至智能下載附件!
作用:
IMAP (Internet Message Access Protocol): 更推薦,郵件保留在服務(wù)器上,多設(shè)備同步,功能更強大(可以操作文件夾)。
POP3 (Post Office Protocol version 3): 郵件通常下載到本地后從服務(wù)器刪除,適合單設(shè)備收取。
2.1 準備: IMAP vs. POP3:選擇你的“收件方式”
[表格:IMAP與POP3對比]
| 特性 | IMAP | POP3 |
|---|---|---|
| 郵件存儲 | 郵件保留在服務(wù)器,本地是同步副本 | 郵件下載到本地后通常從服務(wù)器刪除 |
| 多設(shè)備同步 | ? 完美支持 | ? 不支持,易造成混亂 |
| 功能 | 強大,可操作服務(wù)器文件夾、標記已讀/未讀 | 簡單,僅下載郵件 |
| 推薦 | 現(xiàn)代郵件客戶端首選 | 舊式,不推薦多設(shè)備使用 |
結(jié)論: 對于自動化收取郵件和多設(shè)備同步,IMAP是更優(yōu)的選擇。
2.2 連接郵箱與讀取郵件:讓程序處理你的收件箱
場景: 你需要定期檢查郵箱,篩選出特定發(fā)件人或主題的郵件,讀取其內(nèi)容。
方案: imaplib(或poplib)能讓Python登錄你的郵箱,讀取郵件的元信息(發(fā)件人、主題、日期)和正文,實現(xiàn)Python接收郵件的自動化。
代碼:
import imaplib
import email
from email.header import decode_header
import os
def read_emails_imap(email_address, email_password, imap_server="imap.qq.com"):
"""
通過IMAP協(xié)議連接郵箱,并讀取郵件列表和基本信息。
這是Python接收郵件的基礎(chǔ)。
:param email_address: 郵箱地址
:param email_password: 郵箱授權(quán)碼或密碼
:param imap_server: IMAP服務(wù)器地址
"""
try:
# 連接IMAP服務(wù)器 (SSL加密)
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(email_address, email_password) # 登錄郵箱
mail.select("inbox") # 選擇收件箱 (inbox)
# 搜索所有郵件 (ALL) 或特定條件的郵件 (e.g., 'FROM', 'SUBJECT')
# status, email_ids = mail.search(None, 'FROM', 'sender@example.com') # 篩選發(fā)件人
status, email_ids = mail.search(None, 'ALL') # 搜索所有郵件
email_id_list = email_ids[0].split() # 郵件ID列表
print(f"?? 正在讀取郵箱 '{email_address}' 的郵件...")
print(f" 共找到 {len(email_id_list)} 封郵件。")
# 遍歷郵件ID,獲取郵件信息
for i, email_id in enumerate(email_id_list[-5:]): # 只處理最近5封郵件,避免處理太多
status, msg_data = mail.fetch(email_id, '(RFC822)') # 獲取郵件的完整內(nèi)容
raw_email = msg_data[0][1].decode('utf-8') # 解碼郵件內(nèi)容
msg = email.message_from_string(raw_email) # 解析郵件
subject, encoding = decode_header(msg['Subject'])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding if encoding else 'utf-8')
sender, encoding = decode_header(msg['From'])[0]
if isinstance(sender, bytes):
sender = sender.decode(encoding if encoding else 'utf-8')
print(f"--- 郵件 {i+1} ---")
print(f" 發(fā)件人: {sender}")
print(f" 主題: {subject}")
# print(f" 日期: {msg['Date']}") # 郵件日期
# 獲取郵件正文
# for part in msg.walk():
# ctype = part.get_content_type()
# cdispo = str(part.get('Content-Disposition'))
# if ctype == 'text/plain' and 'attachment' not in cdispo:
# body = part.get_payload(decode=True).decode('utf-8')
# print(" 正文片段:", body[:100], "...") # 打印部分正文
# break
mail.logout() # 登出郵箱
print("? 郵件讀取完成!")
except Exception as e:
print(f"? 讀取郵件失?。簕e}")
print("請檢查郵箱地址、授權(quán)碼、IMAP服務(wù)器地址和網(wǎng)絡(luò)連接。")
if __name__ == "__main__":
# --- 請?zhí)鎿Q為你的實際郵箱信息 ---
my_email = "你的QQ郵箱@qq.com"
my_password = "你的郵箱授權(quán)碼"
read_emails_imap(my_email, my_password)
步驟:
獲取授權(quán)碼: 參照1.1節(jié)獲取你的郵箱授權(quán)碼,并確保IMAP服務(wù)已開啟。
修改代碼信息: 復制上方代碼到VS Code,保存為read_emails_imap.py。修改 my_email 和 my_password。
運行: 在VS Code終端運行 python read_emails_imap.py。
展示:

2.3 智能附件處理:自動下載重要報告,告別手動!
場景: 每天都需要從郵件中下載特定的報告(如“日報”、“月度報告”),但附件多、郵件雜,手動查找下載耗時耗力。
方案: 結(jié)合郵件解析和文件操作,Python能幫你自動識別郵件中的附件,篩選出你需要的附件類型或名稱,并自動下載到指定文件夾,實現(xiàn)郵件附件處理的自動化!
代碼:
import imaplib
import email
from email.header import decode_header
import os
def download_attachments_from_emails(email_address, email_password, imap_server="imap.qq.com",
search_subject="", download_folder="Downloaded_Attachments"):
"""
通過IMAP協(xié)議連接郵箱,搜索特定主題的郵件,并自動下載附件。
這是Python接收郵件和郵件附件處理的核心功能。
:param email_address: 郵箱地址
:param email_password: 郵箱授權(quán)碼或密碼
:param imap_server: IMAP服務(wù)器地址
:param search_subject: 要搜索的郵件主題關(guān)鍵詞 (留空則搜索所有郵件)
:param download_folder: 附件下載保存的文件夾
"""
os.makedirs(download_folder, exist_ok=True) # 確保下載文件夾存在
try:
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(email_address, email_password)
mail.select("inbox")
# 搜索郵件 (可以按主題、發(fā)件人等搜索)
if search_subject:
status, email_ids = mail.search(None, 'SUBJECT', f'"{search_subject}"')
else:
status, email_ids = mail.search(None, 'ALL')
email_id_list = email_ids[0].split()
print(f"?? 正在搜索并下載附件,主題關(guān)鍵詞:'{search_subject}'...")
if not email_id_list:
print(" ?? 未找到符合條件的郵件。")
else:
print(f" 找到 {len(email_id_list)} 封符合條件的郵件。")
for email_id in email_id_list:
status, msg_data = mail.fetch(email_id, '(RFC822)')
raw_email = msg_data[0][1].decode('utf-8')
msg = email.message_from_string(raw_email)
subject, _ = decode_header(msg['Subject'])[0]
subject = subject.decode(_) if isinstance(subject, bytes) else subject
sender, _ = decode_header(msg['From'])[0]
sender = sender.decode(_) if isinstance(sender, bytes) else sender
print(f"--- 處理郵件 (主題: {subject}) ---")
for part in msg.walk():
# 跳過非附件部分
if part.get_content_maintype() == 'multipart' or part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename: # 如果是附件
filename, _ = decode_header(filename)[0] # 解碼附件文件名中的中文
filename = filename.decode(_) if isinstance(filename, bytes) else filename
file_path = os.path.join(download_folder, filename)
try:
with open(file_path, 'wb') as f:
f.write(part.get_payload(decode=True)) # 寫入附件內(nèi)容
print(f" ? 附件已下載:'{filename}'")
except Exception as e:
print(f" ? 下載附件 '{filename}' 失?。簕e}")
mail.logout()
print("? 附件下載完成!")
except Exception as e:
print(f"? 收取郵件或下載附件失敗:{e}")
print("請檢查郵箱地址、授權(quán)碼、IMAP服務(wù)器地址和網(wǎng)絡(luò)連接。")
if __name__ == "__main__":
# --- 請?zhí)鎿Q為你的實際郵箱信息 ---
my_email = "你的QQ郵箱@qq.com"
my_password = "你的郵箱授權(quán)碼"
download_folder_path = os.path.expanduser("~/Desktop/Downloaded_Reports")
os.makedirs(download_folder_path, exist_ok=True) # 確保下載目錄存在
# 示例:搜索主題包含“銷售報告”的郵件,并下載附件
# 建議先手動給你的郵箱發(fā)送幾封帶附件(如PDF、Excel)且主題包含“銷售報告”的測試郵件
download_attachments_from_emails(my_email, my_password,
search_subject="銷售報告",
download_folder=download_folder_path)
步驟:
獲取授權(quán)碼: 參照1.1節(jié)獲取你的郵箱授權(quán)碼,確保IMAP服務(wù)已開啟。
準備測試郵件: 手動向你的郵箱發(fā)送幾封帶附件(例如PDF、Excel文件)且主題包含你設(shè)定的關(guān)鍵詞(例如“銷售報告”)的測試郵件。
修改代碼信息: 復制上方代碼到VS Code,保存為download_attachments.py。修改 my_email、my_password、search_subject 和 download_folder。
運行: 在VS Code終端運行 python download_attachments.py。
展示:

成果:你的智能郵件助手!
恭喜你!通過本篇文章,你已經(jīng)掌握了郵件自動化的各項核心魔法,親手打造了一個能夠一鍵群發(fā)郵件,自動收發(fā)附件的智能郵件助手!
我們深入學習了smtplib和imaplib / poplib等庫,實現(xiàn)了:
- Python發(fā)送郵件: 批量發(fā)送、定制HTML內(nèi)容、自動附加文件,告別郵件群發(fā)的煩惱。
- Python接收郵件: 自動登錄郵箱、篩選郵件,并智能下載附件,告別手動收取。
- 郵件附件處理: 精準識別和保存郵件附件,讓重要報告不遺漏。
- 定時郵件: 結(jié)合schedule庫,可以實現(xiàn)郵件的定時發(fā)送。
總結(jié)與展望:郵件自動化,溝通效率倍增的秘密!
通過本篇文章,你已經(jīng)掌握了郵件自動化的強大能力,為你的辦公自動化之旅又增添了一個重量級技能!你學會了如何利用Python的郵件發(fā)送和接收庫,高效地管理和處理郵件。
除了今天學到的郵件自動化功能,你還希望Python能幫你實現(xiàn)哪些更復雜的郵件管理需求?比如:自動回復特定郵件?根據(jù)郵件內(nèi)容自動分類歸檔?
以上就是基于Python實現(xiàn)一鍵群發(fā)郵件并自動收發(fā)附件功能的詳細內(nèi)容,更多關(guān)于Python群發(fā)郵件并自動收發(fā)附件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python tkinter中的錨點(anchor)問題及處理
提升Python效率之使用循環(huán)機制代替遞歸函數(shù)
Python使用Flask-SQLAlchemy連接數(shù)據(jù)庫操作示例
Pytorch-Geometric中的Message?Passing使用及說明
Python中的NumPy實用函數(shù)整理之percentile詳解
Python實現(xiàn)增強版Docx與JSON雙向轉(zhuǎn)換的完整指南與代碼解析

