Python IMAP读取邮件正文时get_payload返回None问题求助
Hey there! I’ve dealt with this exact head-scratcher before when working with Python’s IMAP library—let’s break down why your content is coming back as None and how to fix it.
Common Reasons & Fixes
1. Your Email is Multipart (Most Likely Culprit)
Emails often come in multiple parts (like plain text + HTML, or with attachments). If you try to grab the body directly from a multipart message, it’ll return None because the actual content lives in the subparts.
Here’s how to handle it properly:
import imaplib import email from email.header import decode_header # Connect to your IMAP server (adjust provider as needed) imap = imaplib.IMAP4_SSL("imap.yourprovider.com") imap.login("your_email@example.com", "your_app_password_or_password") imap.select("INBOX") # Target the inbox, or another folder # Search for emails (use criteria like 'UNSEEN' for unread messages if needed) status, messages = imap.search(None, 'ALL') email_ids = messages[0].split() for email_id in email_ids: # Fetch the full email content status, msg_data = imap.fetch(email_id, "(RFC822)") for response_part in msg_data: if isinstance(response_part, tuple): msg = email.message_from_bytes(response_part[1]) # Decode and print the subject subject, encoding = decode_header(msg["Subject"])[0] if isinstance(subject, bytes): subject = subject.decode(encoding) print(f"\n=== Email Subject: {subject} ===") # Handle multipart messages if msg.is_multipart(): # Iterate through all parts of the email for part in msg.walk(): content_type = part.get_content_type() content_disposition = str(part.get("Content-Disposition")) # Skip attachments to focus on body content if "attachment" not in content_disposition: try: # Decode the payload to get readable text body = part.get_payload(decode=True).decode() if body: print("Email Body:\n", body) except Exception as e: # Catch encoding errors (common with non-standard charsets) print(f"Failed to decode part: {str(e)}") else: # Non-multipart email: extract body directly content_type = msg.get_content_type() body = msg.get_payload(decode=True).decode() if body: print("Email Body:\n", body) # Clean up the connection imap.close() imap.logout()
2. You’re Skipping Payload Decoding
Even for non-multipart emails, you need to use decode=True in get_payload()—most emails are encoded with base64 or quoted-printable. Skipping this step will give you garbled text or None.
3. You’re Ignoring HTML-Only Emails
Some emails only have an HTML body, no plain text. If your code is only checking for text/plain content, it’ll miss the HTML version. The example above checks all non-attachment parts, so it’ll catch both plain text and HTML.
4. Debugging Hack: Inspect the Full Email Structure
Add this line to print the raw email structure—it’ll show you exactly where the content is hiding:
print(msg.as_string())
Look for sections starting with Content-Type: text/plain or text/html—those are the parts you want to extract.
Give these steps a go—9 times out of 10, the issue is just not handling multipart messages correctly. Let me know if you hit any weird edge cases!
内容的提问来源于stack exchange,提问作者robinshion

