我在Windows上运行了一个python 2.7脚本。它登录gmail,检查新的电子邮件和附件:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
file_types = ["pdf", "doc", "docx"] # download attachments with these extentions
login = "login"
passw = "password"
imap_server = "imap.gmail.com"
smtp_server = "smtp.gmail.com"
smtp_port = 587
from smtplib import SMTP
from email.parser import HeaderParser
from email.MIMEText import MIMEText
import sys
import imaplib
import getpass
import email
import datetime
import os
import time
if __name__ == "__main__":
try:
while True:
session = imaplib.IMAP4_SSL(imap_server)
try:
rv, data = session.login(login, passw)
print "Logged in: ", rv
except imaplib.IMAP4.error:
print "Login failed!"
sys.exit(1)
rv, mailboxes = session.list()
rv, data = session.select(foldr)
rv, data = session.search(None, "(UNSEEN)")
for num in data[ 0 ].split():
rv, data = session.fetch(num, "(RFC822)")
for rpart in data:
if isinstance(rpart, tuple):
msg = email.message_from_string(rpart[ 1 ])
to = email.utils.parseaddr(msg[ "From" ])[ 1 ]
text = data[ 0 ][ 1 ]
msg = email.message_from_string(text)
got = []
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
print "file: ", filename
print "Extention: ", filename.split(".")[ -1 ]
if filename.split(".")[ -1 ] not in file_types:
continue
data = part.get_payload(decode = True)
if not data:
continue
date = datetime.datetime.now().strftime("%Y-%m-%d")
if not os.path.isdir("CONTENT"):
os.mkdir("CONTENT")
if not os.path.isdir("CONTENT/" + date):
os.mkdir("CONTENT/" + date)
ftime = datetime.datetime.now().strftime("%H-%M-%S")
new_file = "CONTENT/" + date + "/" + ftime + "_" + filename
f = open(new_file, 'wb')
print "Got new file %s from %s" % (new_file, to)
got.append(filename.encode("utf-8"))
f.write(data)
f.close()
session.close()
session.logout()
time.sleep(60)
except:
print "TARFUN!"
问题是最后一次打印读取垃圾:
=?UTF-8?B?0YfQsNGB0YLRjCAxINGC0LXQutGB0YIg0LzQtdGC0L7QtNC40YfQutC4LmRv?=
例如
所以后来检查不起作用。在linux上它工作得很好。
现在我尝试将d [e]代码文件名设为utf-8。但它没有做任何事情。提前谢谢。
答案 0 :(得分:0)
如果你阅读了定义文件名字段的规范,RFC 2183,第2.3节,它说:
当前[RFC 2045]语法限制参数值(因此 Content-Disposition文件名)到US-ASCII。我们认识到伟大的 允许在文件名中允许任意字符集,但是 定义必要的内容超出了本文档的范围 机制。我们希望基本的[RFC 1521]'价值' 有一天会修改规范以允许使用非US-ASCII 字符,在这个时候应该使用相同的机制 Content-Disposition文件名参数。
有人建议使用RFC来处理这个问题。特别是,有人建议将文件名处理为encoded-word
,由RFC 5987,RFC 2047和RFC 2231定义。简而言之,这意味着RFC 2047格式:
"=?" charset "?" encoding "?" encoded-text "?="
...或RFC 2231格式:
"=?" charset ["*" language] "?" encoded-text "?="
某些邮件代理已经在使用此功能,其他人则不知道如何处理它。 Python 2.x中的email
包是那些不知道如何处理它的包。 (有可能是Python 3.x中的更高版本,或者它可能会在未来发生变化,但如果你想坚持使用2.x,这对你没有帮助。)所以,如果你想解析这个,你必须自己做。
在您的示例中,您有一个RFC 2047格式的文件名,其中包含charset UTF-8
(可直接用作Python编码名称),编码B
,这意味着Base-64,和内容0YfQsNGB0YLRjCAxINGC0LXQutGB0YIg0LzQtdGC0L7QtNC40YfQutC4LmRv
。所以,你必须对它进行base-64解码,然后对其进行UTF-8解码,然后得到u'часть 1 текст методички.do'
。
如果你想更普遍地这样做,你将不得不编写代码,如果可能的话,尝试解释RFC 2231格式的每个文件名,否则,以RFC 2047格式,并执行适当的解码步骤。这段代码在StackOverflow答案中写得非常简单,但基本思路非常简单,如上所示,所以你应该能够自己编写代码。您可能还想搜索PyPI以获取现有实现。