如何按主题关键词和指定日期从Gmail下载附件
解决Gmail按主题关键词+日期筛选下载CSV附件的问题
问题描述
日常工作需要每天从Gmail下载CSV格式的数据文件,目前能通过代码的
fetch()方法按邮件ID下载附件,但希望实现按主题中的特定关键词以及**指定日期(当日或其他日期)**筛选并下载附件,不清楚如何在现有代码中添加这两个筛选功能,附上当前代码:
import imaplib import email import os attachment_dir = 'file/directory' # account credentials user = 'email_adress@gmail.com' password = 'password' imap_url = 'imap.gmail.com' def get_body(msg): if msg.is_multipart(): return get_body(msg.get_payload(0)) else: return msg.get_payload(None, True) # decode def search(key, value, connection): result, data = connection.search(None, key, '"{}"'.format(value)) return data def get_emails(result_bytes): msgs = [] # all the email data are pushed inside an array for num in result_bytes[0].split(): typ, data = connection.fetch(num, '(RFC822)') msgs.append(data) return msgs # it will return an array of bytes separating each email def get_attachment(msg): for part in msg.walk(): if part.get_content_maintype() == 'multipart': continue if part.get('Content-Disposition') is None: continue fileName = part.get_filename() if bool(fileName): filePath = os.path.join(attachment_dir, fileName) if not os.path.isfile(filePath) : fp = open(filePath, 'wb') fp.write(part.get_payload(decode=True)) fp.close() connection = imaplib.IMAP4_SSL(imap_url) connection.login(user, password) connection.select('INBOX') result, data = connection.fetch(b'91', '(RFC822)') # fetch the email body (RFC822) for the given ID, b'91' is the id of the email, you can get it from the search function raw = email.message_from_bytes(data[0][1]) print(get_body(raw)) # prints the raw text of the whole email print(search('FROM', 'email.source@gmail.com',connection)) # search and return uids instead print(get_attachment(raw)) # pass the email to the function
修改后的完整代码
以下代码实现了主题关键词筛选、指定日期筛选,并且只下载CSV格式的附件:
import imaplib import email import os from datetime import datetime # 配置项 attachment_dir = 'file/directory' user = 'email_adress@gmail.com' password = 'password' imap_url = 'imap.gmail.com' # 筛选条件 target_subject_keyword = '每日数据报表' # 替换成你要找的主题关键词 target_date = datetime.today().strftime('%d-%b-%Y') # 当日日期,格式DD-Mon-YYYY,比如05-Jun-2024 # 如需指定其他日期,直接替换成字符串,比如 target_date = '01-Jun-2024' def create_attachment_dir(): # 确保附件目录存在 if not os.path.exists(attachment_dir): os.makedirs(attachment_dir) def search_emails(connection, subject_keyword, target_date): # 组合筛选条件:主题包含关键词 + 日期为指定日期 # IMAP查询语法:AND (SUBJECT "关键词") (ON "日期") search_query = f'(AND (SUBJECT "{subject_keyword}") (ON "{target_date}"))' result, data = connection.search(None, search_query) return data def fetch_email(connection, email_id): # 获取单封邮件的完整内容 typ, data = connection.fetch(email_id, '(RFC822)') return email.message_from_bytes(data[0][1]) def download_csv_attachments(msg): # 只下载CSV格式的附件 for part in msg.walk(): if part.get_content_maintype() == 'multipart': continue if part.get('Content-Disposition') is None: continue filename = part.get_filename() if filename and filename.lower().endswith('.csv'): file_path = os.path.join(attachment_dir, filename) # 避免重复下载(可选,如需覆盖可删除判断) if not os.path.isfile(file_path): with open(file_path, 'wb') as fp: fp.write(part.get_payload(decode=True)) print(f"已下载附件: {filename}") if __name__ == "__main__": create_attachment_dir() # 连接Gmail IMAP服务器 connection = imaplib.IMAP4_SSL(imap_url) connection.login(user, password) connection.select('INBOX') # 搜索符合条件的邮件 email_ids = search_emails(connection, target_subject_keyword, target_date) if email_ids[0]: # 遍历每一封符合条件的邮件 for email_id in email_ids[0].split(): msg = fetch_email(connection, email_id) download_csv_attachments(msg) else: print("未找到符合条件的邮件") # 关闭连接 connection.close() connection.logout()
关键功能说明
- 日期筛选:使用IMAP的
ON参数指定精确日期,格式必须为DD-Mon-YYYY(月份为英文缩写),可以用datetime模块自动生成当日日期,也可以手动指定固定日期 - 主题关键词筛选:使用
SUBJECT参数匹配主题中的关键词,支持模糊匹配(只要主题包含该关键词即可) - 组合筛选:通过
AND将多个筛选条件组合,确保同时满足主题和日期要求 - CSV附件过滤:在下载逻辑中判断文件名后缀为
.csv,避免下载其他格式的附件 - 目录自动创建:添加了目录检查逻辑,确保附件存储目录存在
内容的提问来源于stack exchange,提问作者user20350073
相关产品推荐
相关产品推荐

