Python IMAP 收取邮件
本章节主要提供一个完整的 Python IMAP 收取邮件示例,使用内置模块 imaplib 和 email 接收邮件,包含错误处理、附件支持和多部分邮件解析,适用于大多数邮箱服务。只需修改 imap 服务器地址,用户邮箱账号即可。
代码功能:
- 连接 IMAP 服务器,获取最新 5 封邮件(可通过 max_emails 调整)。
- 解析发件人、主题、日期、正文(优先纯文本,备选 HTML)。
- 支持附件下载(保存到 attachments 文件夹,需设置 save_attachments=True)。
- 包含错误处理,确保代码健壮。
import imaplib
import email
from email.header import decode_header
import os
from datetime import datetime
# qq 邮箱配置
EMAIL = "xxxxxx@qq.com"
PASSWORD = "xxxxxx" # 客户端授权码
IMAP_SERVER = "imap.qq.com" # 使用 imap 而不是 pop3
def fetch_emails(email_address, password, imap_server, max_emails=5, save_attachments=False):
try:
# 连接到 IMAP 服务器
mail = imaplib.IMAP4_SSL(imap_server, timeout=30)
mail.login(email_address, password)
mail.select("inbox", readonly=True)
# 搜索所有邮件
_, data = mail.search(None, "ALL")
email_ids = data[0].split()[-max_emails:] # 获取最新的 max_emails 封邮件
emails = []
for email_id in email_ids:
# 获取邮件内容
_, msg_data = mail.fetch(email_id, "(RFC822)")
email_body = msg_data[0][1]
msg = email.message_from_bytes(email_body)
# 解析邮件主题
subject, encoding = decode_header(msg["subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or "utf-8", errors="ignore")
# 解析发件人和日期
from_ = msg.get("from")
date_ = msg.get("date")
try:
date_ = datetime.strptime(date_, "%a, %d %b %Y %H:%M:%S %z").strftime("%Y-%m-%d %H:%M:%S")
except (ValueError, TypeError):
date_ = date_ or "Unknown Date"
# 解析邮件正文
body = ""
attachments = []
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
# 提取正文
if content_type == "text/plain" and "attachment" not in content_disposition:
try:
body = part.get_payload(decode=True).decode(errors="ignore")
except:
body = "Unable to decode body"
elif content_type == "text/html" and not body:
try:
body = part.get_payload(decode=True).decode(errors="ignore")
except:
body = "Unable to decode body"
# 提取附件
if "attachment" in content_disposition and save_attachments:
filename = part.get_filename()
if filename:
filename, encoding = decode_header(filename)[0]
if isinstance(filename, bytes):
filename = filename.decode(encoding or "utf-8", errors="ignore")
filepath = os.path.join("attachments", filename)
os.makedirs("attachments", exist_ok=True)
with open(filepath, "wb") as f:
f.write(part.get_payload(decode=True))
attachments.append(filepath)
else:
# 非多部分邮件
try:
body = msg.get_payload(decode=True).decode(errors="ignore")
except:
body = "Unable to decode body"
emails.append({
"id": email_id.decode(),
"from": from_,
"subject": subject,
"date": date_,
"body": body[:500] + ("..." if len(body) > 500 else ""),
"attachments": attachments
})
# 关闭连接
mail.logout()
return emails
except Exception as e:
print(f"Error: {str(e)}")
return []
def main():
# 获取邮件
emails = fetch_emails(EMAIL, PASSWORD, IMAP_SERVER, max_emails=5, save_attachments=True)
# 打印邮件信息
for email in emails:
print(f"\nEmail ID: {email['id']}")
print(f"From: {email['from']}")
print(f"Subject: {email['subject']}")
print(f"Date: {email['date']}")
print(f"Body: {email['body']}")
if email['attachments']:
print(f"Attachments: {', '.join(email['attachments'])}")
print("-" * 100)
if __name__ == "__main__":
main()