使用Python发送Outlook电子邮件的方法差异

如何解决使用Python发送Outlook电子邮件的方法差异

我是Python的新手,最近尝试了两种方法来自动在Outlook 365上发送电子邮件,一种方法比另一种方法更成功。我想问一下主要区别是什么,因为它们看起来有很大不同。

第一种方法实质上是在Automate the Boring Stuff书中概述的方法,使用SMTP或IMAP。我尝试了此操作,但由于使用办公计算机的身份验证问题而无法使其正常工作。

对我有用的第二种方法不涉及身份验证,我只需导入win32com客户端和以下代码:

outlook = client.Dispatch('Outlook.Application')
message = outlook.CreateItem(0)
message.Display() 
message.To = "redacted"
message.CC = "redacted"
message.Subject = "Hello"

我想问一下这两种方法的主要区别是什么。似乎第二个可能依赖于打开Outlook并登录我,但是如果我的计算机处于睡眠状态,第一个也可以工作吗?

当我已经登录Windows并无需输入用户ID和密码即可访问Outlook时,为什么要采用涉及身份验证的第一种方法?

我认为这是一个问题,可能对其他刚接触Python和电子邮件自动化的人有用,因为他们在寻找解决方案时可能还会遇到两种方法。

解决方法

tldr;如果您需要从不同的邮箱发送邮件,请使用 smtplib。如果您要自动化可以使用 Outlook 手动执行的操作,请使用 win32com.client

SMTP

参考用于 SMTP 的官方 python docs,那里描述的方法只是允许您发送邮件。 (是的,就是这样。您甚至无法查看收件箱。您将需要 imaplibpoplib。)

对我来说 smtp 的优点是,如果您有他/她的凭据,您可以从另一个人的邮箱发送电子邮件。如果您要使用 win32com.client,则需要退出您自己的 Outlook,登录到该特定人员的 Outlook,然后运行代码。对我来说,我面临的问题是我必须等待他/她的收件箱完成加载,然后才能发送任何内容。如果您只需要从多个邮箱发送邮件(并且对读取或删除邮件等任何其他功能不感兴趣),则这是不可行的。

[更新] 我最近在一个个人项目中使用了 smtplibemail(一个 Python 内置包)。由于这是个人项目,我不想使用我的办公室电子邮件,因此我决定使用 smtplib 代替。虽然需要设置初始连接,但它非常简单。由于无法在发送前将电子邮件保存为草稿,因此合乎逻辑的解决方法是将其发送到您自己的电子邮件地址(或任何其他“安全”电子邮件)以测试它是否按预期工作。

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg['From'] = 'YOUR_EMAIL@GMAIL.COM'
msg['Subject'] = 'Some subject here'
msg['To'] = ','.join(['adam@gmail.com','bob@gmail.com','candice@gmail.com'])
        
msg.set_content('Some text here')

with smtplib.SMTP_SSL('smtp.gmail.com',465) as smtp:
    smtp.login('YOUR_EMAIL@GMAIL.COM','PASSWORD123')
    smtp.send_message(msg)
    print('Email sent!')

win32com.client(专注于 Outlook 应用程序)

如果您想自动化您可以在您有权访问的 Outlook 邮箱上执行的操作,则应使用此库。语法往往更简单,它允许您做不可能的事情仅使用 smtplib

这里有两个例子来说明我的观点。

示例 1:自动发送日历邀请

如果您要使用 SMTP 执行此操作,则需要更多代码和另一个库 email,特别是 .MIMEMultipart.MIMEBase.MIMEText、{{1} }.至少可以说,语法看起来令人生畏。看看下面的 stackoverflow answer.Utils 变量:

ical

ical = "BEGIN:VCALENDAR"+CRLF+"PRODID:pyICSParser"+CRLF+"VERSION:2.0"+CRLF+"CALSCALE:GREGORIAN"+CRLF ical+="METHOD:REQUEST"+CRLF+"BEGIN:VEVENT"+CRLF+"DTSTART:"+dtstart+CRLF+"DTEND:"+dtend+CRLF+"DTSTAMP:"+dtstamp+CRLF+organizer+CRLF ical+= "UID:FIXMEUID"+dtstamp+CRLF ical+= attendee+"CREATED:"+dtstamp+CRLF+description+"LAST-MODIFIED:"+dtstamp+CRLF+"LOCATION:"+CRLF+"SEQUENCE:0"+CRLF+"STATUS:CONFIRMED"+CRLF ical+= "SUMMARY:test "+ddtstart.strftime("%Y%m%d @ %H:%M")+CRLF+"TRANSP:OPAQUE"+CRLF+"END:VEVENT"+CRLF+"END:VCALENDAR"+CRLF 简单多了(呸~)。互联网上到处都是代码示例(herehere),下面是一个简单的示例:

win32com.client

示例 2:将电子邮件保存为草稿

我经常为同事自动完成工作,当您批量发送电子邮件时,强烈建议将创建的邮件项保存为草稿进行测试。 ol = w32.Dispatch('Outlook.Application') appt = ol.CreateItem(1) appt.Start = '2021-02-06 15:00' appt.Save() 允许您将邮件项保存为草稿(即 win32com.client),但 .Save() 不允许您这样做(重申一下,它只允许您发送邮件。)>

[免责声明] 我在 Outlook 上做了一些自动化工作,我一直使用 smtplib,我最近才开始将 win32com.client 用于个人项目。这个问题引起了我的兴趣,我决定是时候至少阅读更多关于 smtplib 的信息了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-