You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python email库获取邮件附件名称失败求助

Fixing "None" Attachment Filenames in Python's Email Module

Hey, let's troubleshoot why you're getting None instead of the actual attachment filename! I’ve dealt with this exact issue before, so here’s what’s probably going wrong and how to fix it:

1. Your code misses filenames stored in Content-Type headers

Some email attachments don’t use the Content-Disposition header to store the filename—instead, they tuck it into the name parameter of the Content-Type header. Your original code skips these entirely because it checks if Content-Disposition is None and moves on.

2. Filenames might be encoded (RFC 2047)

Many emails encode filenames with non-ASCII characters using RFC 2047 standards. The raw get_filename() call will return this encoded string (or None if it can’t parse it), so you need to decode it properly.

Here’s the fixed code

Let’s update your code to handle both cases and decode encoded filenames:

import email
from email.header import decode_header

def decode_filename(filename):
    if not filename:
        return None
    # Decode RFC 2047 encoded filenames
    decoded_parts = decode_header(filename)
    decoded_name = []
    for part, encoding in decoded_parts:
        if isinstance(part, bytes):
            # Use utf-8 as fallback if encoding is unknown
            decoded_name.append(part.decode(encoding or 'utf-8'))
        else:
            decoded_name.append(part)
    return ''.join(decoded_name)

def get_attachment_filename(part):
    # First try to get filename from Content-Disposition
    filename = part.get_filename()
    if filename:
        return decode_filename(filename)
    # If that fails, check Content-Type's name parameter
    for param_name, param_value in part.get_params():
        if param_name.lower() == 'name':
            return decode_filename(param_value)
    # No filename found
    return None

# Process the email
mail = email.message_from_string(bytes.decode(email_body))
if mail.get_content_maintype() != 'multipart':
    print("This email doesn't contain attachments.")
else:
    for part in mail.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        # Try to get the filename regardless of Content-Disposition
        attachment_name = get_attachment_filename(part)
        if attachment_name:
            print(f"Found attachment: {attachment_name}")

How this works:

  • The decode_filename function handles encoded filenames, converting them to readable text.
  • get_attachment_filename checks both Content-Disposition and Content-Type headers for the filename.
  • We removed the check for Content-Disposition is None so we don’t skip attachments that store filenames elsewhere.

If you’re still having issues, try adding print(part.items()) inside the loop to see all the headers for each part—this will help you spot where the filename is hiding.

内容的提问来源于stack exchange,提问作者Kuldeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:18:16