python - 如何在 Python 中使用 email.message.EmailMessage 类处理传入的电子邮件?
问题描述
我做了一个传入的电子邮件处理程序,但它太大了,我认为它可以简化。我已阅读模块电子邮件文档并找到类 EmailMessage,但我不明白如何处理传入的电子邮件。我怎么能这样做?
contents = sys.stdin.read()
msg = email.message_from_string(contents)
解决方案
官方文档中给出了使用电子邮件库解析电子邮件的一个很好的现代示例:
import os
import sys
import tempfile
import mimetypes
import webbrowser
# Import the email modules we'll need
from email import policy
from email.parser import BytesParser
# An imaginary module that would make this work and be safe.
from imaginary import magic_html_parser
# In a real program you'd get the filename from the arguments.
with open('outgoing.msg', 'rb') as fp:
msg = BytesParser(policy=policy.default).parse(fp)
# Now the header items can be accessed as a dictionary, and any non-ASCII will
# be converted to unicode:
print('To:', msg['to'])
print('From:', msg['from'])
print('Subject:', msg['subject'])
# If we want to print a preview of the message content, we can extract whatever
# the least formatted payload is and print the first three lines. Of course,
# if the message has no plain text part printing the first three lines of html
# is probably useless, but this is just a conceptual example.
simplest = msg.get_body(preferencelist=('plain', 'html'))
print()
print(''.join(simplest.get_content().splitlines(keepends=True)[:3]))
ans = input("View full message?")
if ans.lower()[0] == 'n':
sys.exit()
# We can extract the richest alternative in order to display it:
richest = msg.get_body()
partfiles = {}
if richest['content-type'].maintype == 'text':
if richest['content-type'].subtype == 'plain':
for line in richest.get_content().splitlines():
print(line)
sys.exit()
elif richest['content-type'].subtype == 'html':
body = richest
else:
print("Don't know how to display {}".format(richest.get_content_type()))
sys.exit()
elif richest['content-type'].content_type == 'multipart/related':
body = richest.get_body(preferencelist=('html'))
for part in richest.iter_attachments():
fn = part.get_filename()
if fn:
extension = os.path.splitext(part.get_filename())[1]
else:
extension = mimetypes.guess_extension(part.get_content_type())
with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f:
f.write(part.get_content())
# again strip the <> to go from email form of cid to html form.
partfiles[part['content-id'][1:-1]] = f.name
else:
print("Don't know how to display {}".format(richest.get_content_type()))
sys.exit()
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
# The magic_html_parser has to rewrite the href="cid:...." attributes to
# point to the filenames in partfiles. It also has to do a safety-sanitize
# of the html. It could be written using html.parser.
f.write(magic_html_parser(body.get_content(), partfiles))
webbrowser.open(f.name)
os.remove(f.name)
for fn in partfiles.values():
os.remove(fn)
# Of course, there are lots of email messages that could break this simple
# minded program, but it will handle the most common ones.
推荐阅读
- python - 使用 Python 遍历嵌套列表
- php - CakePHP - 在 null 上调用成员函数 allow()
- excel - IF 函数,条件乘法
- protractor - 如何使用量角器/黄瓜/打字稿在测试框架中以无头模式截屏
- embedded-linux - Yocto PREMIRROR/SOURCE_MIRROR_URL 可能带有 url 参数(SAS_TOKEN)?
- json - 从 jq 生成表格输出
- javascript - 正则表达式接受任何值,但在 javascript 中的最大长度为 200
- android - 如何动态强制小部件向右移动?
- excel - 计算空单元格的动态范围
- javascript - Vue 将文本从动态创建的组件复制到剪贴板