admin管理员组文章数量:1566220
借鉴:python高阶教程-使用imap接收邮箱的附件(中文字符编码与MIME) - 码农教程
原版运行代码
import imaplib
import email
from email.parser import BytesParser
from email.utils import parseaddr
# 如果是企业邮箱,host要更换成企业邮箱的
host = 'imap.qq'
user = 'xxxxx@qq'
# 不是登录password,是单独生成的邮箱authCode
passwd = ''
mail_directory = 'INBOX'
conn = imaplib.IMAP4(host)
conn.login(user, passwd)
conn.select(mail_directory)
# status, data = conn.search(None, 'ALL')
# 多条件:来自xxx发件人,未读
status, data = conn.search(None, '(FROM "xxx@qq") UNSEEN')
email_list = list(reversed(data[0].split()))
def decode_str(s):
try:
subject = email.header.decode_header(s)
except:
# print('Header decode error')
return None
sub_bytes = subject[0][0]
sub_charset = subject[0][1]
if None == sub_charset:
subject = sub_bytes
elif 'unknown-8bit' == sub_charset:
subject = str(sub_bytes, 'utf8')
else:
subject = str(sub_bytes, sub_charset)
return subject
def get_email(num, conn):
typ, content = conn.fetch(num, '(RFC822)')
msg = BytesParser().parsebytes(content[0][1])
sub = msg.get('Subject')
for part in msg.walk():
fileName = part.get_filename()
fileName = decode_str(fileName)
if None != fileName:
print('+++++++++++++++++++')
print(fileName)
print(num, decode_str(sub))
for num in email_list:
get_email(num, conn)
conn.close()
conn.logout()
获取附件
附件的获取按照网络上的代码没有出现问题.
for part in message.walk():
fileName = part.get_filename()
fileName = decode_str(fileName)
# 保存附件
if fileName:
data = part.get_payload(decode=True)
localFileName = "D:\\" + fileName
with open(localFileName,'wb') as f:
f.write(data)
print("附件%s已保存" % fileName)
按时间搜索
不能有时间,只能有日期,而且格式是日月年
以下为引用:Python imaplib 搜索带有日期和时间的电子邮件
“不幸的是没有。 中定义的通用IMAP搜索语言RFC 3501 §6.4.4不包括任何按时间搜索的规定。
SINCE
被定义为取一个<date>
项,该项又被定义为date-day "-" date-month "-" date-year
,可以带或不带引号。
IMAP甚至没有时区意识,所以你将不得不根据INTERNALDATE
项,在本地过滤掉不符合你范围的前几条信息。 你甚至可能要多取几天的信息。
如果你使用的是Gmail,你也许可以使用Gmail的搜索语言,它可以作为一个extension.”
搜索其他文件夹
众所周知,收件箱统一交inbox,但是自定义或者其他文件呢?
有一个命令可以看到自己邮箱下那些文件夹的具体名称
import imaplib
import email
from email.parser import BytesParser
from email.utils import parseaddr
# 如果是企业邮箱,host要更换成企业邮箱的
host = 'imap.qq'
user = 'xxxxx@qq'
# 不是登录password,是单独生成的邮箱authCode
passwd = ''
conn = imaplib.IMAP4(host)
conn.login(user, passwd)
# 登录后使用
conn.list()
'''('OK',
[b'(\\NoSelect \\HasChildren) "/" "&UXZO1mWHTvZZOQ-"',
b'(\\HasNoChildren) "/" "INBOX"',
b'(\\HasNoChildren) "/" "Sent Messages"',
b'(\\HasNoChildren) "/" "Drafts"',
b'(\\HasNoChildren) "/" "Deleted Messages"',
b'(\\HasNoChildren) "/" "Junk"'])'''
mail_directory = 'Sent Messages'
conn.select("\"" + mail_directory + "\"")
# status, data = conn.search(None, 'ALL')
# 多条件:来自xxx发件人,未读
status, data = conn.search(None, '(FROM "xxx@qq") UNSEEN')
email_list = list(reversed(data[0].split()))
如果文件夹名有空格,一定要按照一下格式写!
email-Python imaplib 无法选择()自定义 Gmail 标签 - 糯米PHP
与朋友讨论了几个小时后解决了这个问题。事实证明,问题是 imap.select() 想要在邮箱名称周围加上引号,如果它包含空格。所以 imap.select("INBOX") 很好,但有空格你需要 imap.select("\"" + "Label Name" + "\"")
最有效的搜索方式
试验了一个晚上,发现inbox通过:发件人,日期,是否已读来搜索是最有效的,理论上按照subject应该也是可以的,但是我试了半天,如果使用中文搜索,完全不行,都会搜到一大堆,根本不能完全匹配,只有标题里有英文,通过那个英文搜索才可以完全匹配!
发件人 未读 日期
conn = imaplib.IMAP4(host)
conn.login(user, passwd)
conn.select('INBOX')
status, data = conn.search(None, '(FROM "xxxx@qq") UNSEEN SINCE "05-04-2023"')
标题中含有‘hk_us’的邮件
conn = imaplib.IMAP4(host)
conn.login(user, passwd)
conn.select('INBOX')
status, data = conn.search(None, 'SUBJECT "hk_us"')
标记为已读
import imaplib
import email
from email.parser import BytesParser
from email.utils import parseaddr
# 如果是企业邮箱,host要更换成企业邮箱的
host = 'imap.qq'
user = 'xxxxx@qq'
# 不是登录password,是单独生成的邮箱authCode
passwd = ''
mail_directory = 'INBOX'
conn = imaplib.IMAP4(host)
conn.login(user, passwd)
conn.select(mail_directory)
# status, data = conn.search(None, 'ALL')
# 多条件:来自xxx发件人,未读
status, data = conn.search(None, '(FROM "xxx@qq") UNSEEN')
email_list = list(reversed(data[0].split()))
def decode_str(s):
try:
subject = email.header.decode_header(s)
except:
# print('Header decode error')
return None
sub_bytes = subject[0][0]
sub_charset = subject[0][1]
if None == sub_charset:
subject = sub_bytes
elif 'unknown-8bit' == sub_charset:
subject = str(sub_bytes, 'utf8')
else:
subject = str(sub_bytes, sub_charset)
return subject
def get_email(num, conn):
typ, content = conn.fetch(num, '(RFC822)')
msg = BytesParser().parsebytes(content[0][1])
sub = msg.get('Subject')
for part in msg.walk():
fileName = part.get_filename()
fileName = decode_str(fileName)
if None != fileName:
print('+++++++++++++++++++')
print(fileName)
# 标记为已读
conn.store(num,'+FLAGS','\Seen')
print(num, decode_str(sub))
for num in email_list:
get_email(num, conn)
conn.close()
conn.logout()
获取邮件时间
引用:PYTHON 获取邮件发送时间_获取邮件日期_稚麟的博客-CSDN博客
def get_email(num, conn):
typ, content = conn.fetch(num, '(RFC822)')
msg = BytesParser().parsebytes(content[0][1])
# 获得标题
sub = msg.get('Subject')
# 获得邮件时间
mailDate = msg.get("Date")
mailDate = mailDate.split(',')[1]
mailDate = datetime.datetime.strptime(mailDate,'%d %b %Y %H:%M:%S %z').strftime('%Y%m%d%H%M%S')
我用的腾讯邮箱,他里面的日期是以下这样:
Tue, 24 Aug 2021 09:17:00 +0800 (CST)
Mon, 23 Aug 2021 09:35:26 +0000 (UTC)
Wed, 28 Jul 2021 00:51:23 +0000 (GMT)
用split(),把星期去掉,只处理后面的
更有效的连接邮箱,接收邮件
好吧,这是一种尝试和尝试的方法,但最终我们得到了一个解决方案,虽然不是最佳的,但黑客是每次在脚本从睡眠中唤醒后都重新连接一次,以便从开始获取收件箱,这很容易做到通过刷新页面(就像我们在普通浏览器中重新加载一样),所以看起来可能像这样:
mail = imaplib.IMAP4_SSL('imap.gmail')
mail.login(user,passwd)
while True:
mail.select("inbox")
result, idData = mail.uid('search', query, "ALL")
processIDs(idData)
time.sleep(60)
借鉴:Python Imaplib:无需重新连接即可获取新的Gmail邮件 |
版权声明:本文标题:【转载+原创】python imaplib读邮件,存附件至本地,标记为已读,搜索邮件-腾讯qq邮箱 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1725783732a1042462.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论