如何用Python win32com.client库打开Outlook邮件并点击下载按钮?
解决方案:通过Python处理Outlook邮件中的下载链接
一、批处理启动/关闭Outlook脚本
启动Outlook(start_outlook.bat)
@echo off start outlook.exe exit
关闭Outlook(close_outlook.bat)
@echo off taskkill /im outlook.exe /f exit
二、Python处理邮件下载链接的核心思路
之前的代码是直接下载附件,现在需要提取邮件正文中的下载链接,优先用requests直接下载(比模拟点击更稳定高效),如果链接需要登录验证,再考虑模拟浏览器操作。
三、修改后的Python代码
先安装依赖库:
pip install requests beautifulsoup4
替换原附件处理逻辑,改为提取链接并下载:
import os import re import win32com.client from pathlib import Path import requests from bs4 import BeautifulSoup from urllib.parse import urljoin # 配置下载路径,自行修改 download_path = 'your/download/path/here' os.makedirs(download_path, exist_ok=True) # 连接Outlook outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") inbox = outlook.GetDefaultFolder(6) # 6对应收件箱 messages = inbox.Items messages.Sort("[ReceivedTime]", True) # 按接收时间倒序,优先处理最新邮件 def download_from_mail(subject_keyword): for message in messages: # 用关键词模糊匹配主题,避免带时间后缀的主题匹配失败 if subject_keyword in message.Subject and message.Unread: print(f"正在处理邮件:{message.Subject}") # 优先解析HTML格式正文(更准确) if message.HTMLBody: soup = BeautifulSoup(message.HTMLBody, 'html.parser') download_links = [] # 筛选带下载关键词的链接,自行调整关键词 for a_tag in soup.find_all('a', href=True): link_text = a_tag.get_text(strip=True).lower() link_href = a_tag['href'] if 'download' in link_text or '下载' in link_text or 'report' in link_href.lower(): # 补全相对链接 full_link = urljoin("https://", link_href) if not link_href.startswith(('http://', 'https://')) else link_href download_links.append(full_link) if download_links: print(f"找到下载链接:{download_links}") # 批量下载链接对应文件 for idx, link in enumerate(download_links): try: response = requests.get(link, stream=True) response.raise_for_status() # 自动提取文件名,无则用默认名 filename = link.split('/')[-1] or f"report_{idx+1}.xlsx" save_path = os.path.join(download_path, filename) with open(save_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f"文件已保存:{save_path}") except Exception as e: print(f"下载失败:{link},错误信息:{str(e)}") else: print("未找到匹配的下载链接") else: # 处理纯文本格式的邮件正文 body_text = message.Body links = re.findall(r'https?://\S+', body_text) if links: print(f"找到纯文本链接:{links}") for idx, link in enumerate(links): try: response = requests.get(link, stream=True) response.raise_for_status() filename = link.split('/')[-1] or f"report_{idx+1}.xlsx" save_path = os.path.join(download_path, filename) with open(save_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f"文件已保存:{save_path}") except Exception as e: print(f"下载失败:{link},错误信息:{str(e)}") else: print("邮件正文中未找到有效链接") # 标记邮件为已读 message.Unread = False break # 处理完第一封匹配的未读邮件后退出,如需处理多封可删除此行 # 调用函数,传入主题关键词(模糊匹配) download_from_mail('Scheduled Report BI Report - All NPIs')
四、关键注意事项
- Outlook权限:首次运行可能弹出安全提示,需要在Outlook设置中允许程序访问邮件,或手动授权一次。
- 链接验证:如果下载链接需要公司内部账号登录,
requests直接下载会失败,此时可以改用selenium模拟浏览器登录后点击下载。 - 主题匹配:用关键词模糊匹配比完全匹配更可靠,避免主题带时间后缀导致匹配失败。
- 文件类型:根据实际下载的文件类型,调整默认文件名的后缀(比如
.csv、.pdf)。
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

