Featured image of post Python Basic 16 imaplib 读取邮件

Python Basic 16 imaplib 读取邮件

本篇文章主要介绍用 Python imaplib 读取邮件

Python的imaplib库是处理IMAP协议的标准库,让我们能够连接到邮件服务器并读取邮件内容~下面是一个超详细的教程!(●ˊωˋ●)

基本连接设置

首先需要导入库并建立连接:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import imaplib
import email
from email.header import decode_header

# 连接服务器 (以QQ邮箱为例)
imap_server = "imap.qq.com"
username = "your_email@qq.com"
password = "your_password_or_app_password"  # 建议使用应用专用密码更安全哦~

# 创建IMAP4_SSL连接 (◕‿◕✿)
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(username, password)

选择邮箱文件夹

登录后选择要读取的文件夹:

1
2
3
4
5
# 列出所有文件夹 (ノ◕ヮ◕)ノ*:・゚✧
mail.list()  # 返回所有可用的邮箱文件夹

# 选择收件箱(默认是INBOX)
mail.select("INBOX")  # 也可以换成其他文件夹如"Sent", "Drafts"等

搜索邮件 (★ω★)

使用search()方法查找邮件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 搜索所有未读邮件 ✧*。٩(ˊωˋ*)و✧*。
status, messages = mail.search(None, 'UNSEEN')

# 搜索特定发件人的邮件
status, messages = mail.search(None, 'FROM "someone@example.com"')

# 搜索包含特定主题的邮件
status, messages = mail.search(None, 'SUBJECT "重要通知"')

# 搜索特定日期之后的邮件 (格式:DD-MMM-YYYY)
status, messages = mail.search(None, 'SINCE "01-Jan-2023"')

# 组合多个条件搜索
status, messages = mail.search(None, '(UNSEEN FROM "boss@company.com" SINCE "01-Jan-2023")')

获取邮件内容 ٩(◕‿◕。)۶

获取邮件ID后可以读取邮件内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 获取邮件ID列表
messages = messages[0].split()  # 转换为列表

# 获取最新的一封邮件 (最后一个ID)
latest_email_id = messages[-1]

# 获取完整的邮件内容
status, msg_data = mail.fetch(latest_email_id, "(RFC822)")
raw_email = msg_data[0][1]

# 解析邮件内容
msg = email.message_from_bytes(raw_email)

# 获取邮件主题 (●'◡'●)
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
    subject = subject.decode(encoding if encoding else "utf-8")

# 获取发件人信息
from_ = msg.get("From")
print(f"主题: {subject}")
print(f"发件人: {from_}")

读取邮件正文和附件 ε==3

邮件可能有多种格式,我们需要处理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def get_email_body(msg):
    """递归获取邮件正文内容"""
    if msg.is_multipart():
        for part in msg.walk():
            content_type = part.get_content_type()
            content_disposition = str(part.get("Content-Disposition"))
          
            # 附件跳过 (`・ω・´)
            if "attachment" in content_disposition:
                continue
              
            # 递归处理多部分邮件
            body = get_email_body(part)
            if body:
                return body
    else:
        content_type = msg.get_content_type()
        if content_type == "text/plain" or content_type == "text/html":
            # 获取邮件内容并解码 (ノ◕ヮ◕)ノ*:・゚✧
            content = msg.get_payload(decode=True)
            charset = msg.get_content_charset() or "utf-8"
            return content.decode(charset)
    return None

# 获取邮件正文
body = get_email_body(msg)
if body:
    print("邮件正文:")
    print(body[:500] + "...")  # 只打印前500个字符避免太长

下载邮件附件 ٩(◕‿◕。)۶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import os

def save_attachments(msg, download_folder="attachments"):
    """保存邮件附件"""
    if not os.path.isdir(download_folder):
        os.makedirs(download_folder)
      
    for part in msg.walk():
        content_disposition = str(part.get("Content-Disposition"))
      
        if "attachment" in content_disposition:
            # 获取文件名 (★ω★)
            filename = part.get_filename()
            if filename:
                filename, encoding = decode_header(filename)[0]
                if isinstance(filename, bytes):
                    filename = filename.decode(encoding if encoding else "utf-8")
              
                # 保存附件 ε==3
                filepath = os.path.join(download_folder, filename)
                with open(filepath, "wb") as f:
                    f.write(part.get_payload(decode=True))
                print(f"附件已保存: {filepath}")

save_attachments(msg)

完整示例 (✧ω✧)

这里是一个完整的读取最新5封未读邮件的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import imaplib
import email
from email.header import decode_header
import os

def read_emails(email_account, password, max_emails=5):
    # 1. 连接服务器 ٩(◕‿◕。)۶
    mail = imaplib.IMAP4_SSL("imap.qq.com")
    mail.login(email_account, password)
    mail.select("INBOX")
  
    # 2. 搜索未读邮件 ✧*。٩(ˊωˋ*)و✧*。
    status, messages = mail.search(None, "UNSEEN")
    if status != "OK":
        print("没有找到邮件")
        return
      
    email_ids = messages[0].split()
    email_ids = email_ids[-max_emails:]  # 只处理最新的几封
  
    print(f"找到 {len(email_ids)} 封未读邮件:")
  
    # 3. 处理每封邮件 (●'◡'●)
    for email_id in reversed(email_ids):
        status, msg_data = mail.fetch(email_id, "(RFC822)")
        if status != "OK":
            continue
          
        msg = email.message_from_bytes(msg_data[0][1])
      
        # 解析邮件头部信息 (★ω★)
        subject, encoding = decode_header(msg["Subject"])[0]
        subject = subject.decode(encoding) if isinstance(subject, bytes) else subject
        from_ = msg.get("From")
        date = msg.get("Date")
      
        print("\n" + "="*50)
        print(f"主题: {subject}")
        print(f"发件人: {from_}")
        print(f"日期: {date}")
      
        # 获取邮件正文 (ノ◕ヮ◕)ノ*:・゚✧
        body = get_email_body(msg)
        if body:
            print("\n邮件内容:")
            print(body[:500] + ("..." if len(body) > 500 else ""))
      
        # 保存附件 ε==3
        save_attachments(msg)
  
    # 4. 关闭连接 (。•̀ᴗ-)✧
    mail.close()
    mail.logout()

# 使用示例 (ノ◕ヮ◕)ノ*:・゚✧
read_emails("your_email@qq.com", "your_app_password")

注意事项 ⚠️

  1. 安全提示 (`・ω・´):

    • 不要将密码直接写在代码中!可以使用环境变量或配置文件
    • 建议使用应用专用密码而非主密码
  2. 性能优化 (ノ◕ヮ◕)ノ*:・゚✧:

    • 处理大量邮件时,可以分批获取
    • 考虑使用IDLE命令实现推送通知
  3. 常见错误处理 (╯°□°)╯:

    1
    2
    3
    4
    5
    6
    7
    
    try:
        mail = imaplib.IMAP4_SSL(imap_server)
        mail.login(username, password)
    except imaplib.IMAP4.error as e:
        print(f"登录失败: {e}")
    except Exception as e:
        print(f"发生错误: {e}")
    
  4. 最后别忘记关闭连接! (。•ᴗ-)✧

    1
    2
    
    mail.close()
    mail.logout()
    

掌握了这些技能,你就能愉快地用Python自动处理邮件啦!(ノ≧∀≦)ノ

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计