通过 Python 发送 Outlook 电子邮件?

Posted

技术标签:

【中文标题】通过 Python 发送 Outlook 电子邮件?【英文标题】:Send Outlook Email Via Python? 【发布时间】:2011-09-14 00:35:51 【问题描述】:

我正在使用Outlook 2003

使用Python 发送电子邮件(通过Outlook 2003)的最佳方式是什么?

【问题讨论】:

@ThiefMaster: 我的smtp 服务器与我的电子邮件不同——因此,我需要通过我的互联网提供商 (att) 发送邮件至channel 我的 smtp,即使我正在使用另一个电子邮件地址(不是att's)来发送电子邮件。 Outlook 已配置为处理此问题。如果有其他解决方案(不基于Outlook)也支持这一点,我很乐意听取建议。 正确的解决方案是使用python的smtplib 【参考方案1】:
import win32com.client as win32
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = 'To address'
mail.Subject = 'Message subject'
mail.Body = 'Message body'
mail.htmlBody = '<h2>HTML Message body</h2>' #this field is optional

# To attach a file to the email (optional):
attachment  = "Path to the attachment"
mail.Attachments.Add(attachment)

mail.Send()

将使用您本地的 Outlook 帐户发送。

请注意,如果您尝试执行上述未提及的操作,请查看 COM 文档属性/方法:https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/mailitem-object-outlook。在上面的代码中,mail 是一个 MailItem 对象。

【讨论】:

更新了答案。 mail.HTMLBody 允许您将其设置为 html 字符串 简单直接的答案!在 Python 3.6.1 中正常工作。 @ViktorDemin 查看官方 COM 文档,msdn.microsoft.com/en-us/vba/outlook-vba/articles/…,我会尝试 mail.ReadReceiptRequested = True @pyd 尝试在mail.To = "a@b.com;c@d.com" 中使用冒号分隔的电子邮件字符串,让我知道它是否有效 @Ukrainian-serge 看看pbpython.com/windows-com.html 和docs.microsoft.com/de-de/windows/win32/com/…【参考方案2】:

有关使用 Outlook 的解决方案,请参阅下面 TheoretiCAL 的答案。

否则,使用python自带的smtplib。请注意,这将要求您的电子邮件帐户允许 smtp,默认情况下不一定启用。

SERVER = "smtp.example.com"
FROM = "yourEmail@example.com"
TO = ["listOfEmails"] # must be a list

SUBJECT = "Subject"
TEXT = "Your Text"

# Prepare actual message
message = """From: %s\r\nTo: %s\r\nSubject: %s\r\n\

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail
import smtplib
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO, message)
server.quit()

编辑:此示例使用RFC2606中所述的保留域

SERVER = "smtp.example.com"
FROM = "johnDoe@example.com"
TO = ["JaneDoe@example.com"] # must be a list

SUBJECT = "Hello!"
TEXT = "This is a test of emailing through smtp of example.com."

# Prepare actual message
message = """From: %s\r\nTo: %s\r\nSubject: %s\r\n\

%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)

# Send the mail
import smtplib
server = smtplib.SMTP(SERVER)
server.login("MrDoe", "PASSWORD")
server.sendmail(FROM, TO, message)
server.quit()

要真正使用 gmail,Doe 先生需要转到 gmail 中的选项选项卡并将其设置为允许 smtp 连接。

注意添加登录行以对远程服务器进行身份验证。原始版本不包含此内容,这是我的疏忽。

【讨论】:

这不是问题所在。问题是关于使用 Win32 API 来控制 Outlook @Spencer Rathbun:谢谢。问题是这样的:我的smtp 服务器与我的电子邮件不同——因此,即使我使用不同的电子邮件地址(不是att's) 发送电子邮件。 Outlook 已配置为处理此问题。如果有其他解决方案(不基于Outlook)也支持这一点,我很乐意听取建议。 @user3262424 所以你的email地址和你的smtp服务器不一样?这应该在 smtp 服务器上处理。需要将其设置为将并非源自那里的电子邮件传递到正确的电子邮件服务器。设置不正确,这会使垃圾邮件发送者循环通过您。但是大概,您知道所涉及的 IP 地址,并且可以将它们设置在允许列表中。 @Spencer Rathbun:谢谢,但我不确定如何使用您的脚本。我没有成功使用它发送电子邮件。 如果你是,上帝保佑,在公司防火墙后面,你只能通过 Outlook 发送邮件。【参考方案3】:

通过谷歌查看,有很多例子,见here 一个。

内嵌以便于查看:

import win32com.client

def send_mail_via_com(text, subject, recipient, profilename="Outlook2003"):
    s = win32com.client.Dispatch("Mapi.Session")
    o = win32com.client.Dispatch("Outlook.Application")
    s.Logon(profilename)

    Msg = o.CreateItem(0)
    Msg.To = recipient

    Msg.CC = "moreaddresses here"
    Msg.BCC = "address"

    Msg.Subject = subject
    Msg.Body = text

    attachment1 = "Path to attachment no. 1"
    attachment2 = "Path to attachment no. 2"
    Msg.Attachments.Add(attachment1)
    Msg.Attachments.Add(attachment2)

    Msg.Send()

【讨论】:

谢谢,这很好。问题是,Outlook 不断生成alert message,询问我是否要继续或终止访问脚本。有没有办法跳过这个alert message @user3262424 - 弹出窗口的确切内容是什么? 我现在不在那台电脑旁边。通知脚本正在尝试访问 outlook 并且它可能是病毒等,如果我想继续的话。 那可能是一些防病毒插件在进行电子邮件筛选。我怀疑您是否可以绕过它而无需在桌面上手动操作来禁用它。烦人。 有没有办法在没有win32 模块的Mac OS 上做同样的事情?【参考方案4】:

使用pywin32:

from win32com.client import Dispatch

session = Dispatch('MAPI.session')
session.Logon('','',0,1,0,0,'exchange.foo.com\nUserName');
msg = session.Outbox.Messages.Add('Hello', 'This is a test')
msg.Recipients.Add('Corey', 'SMTP:corey@foo.com')
msg.Send()
session.Logoff()

【讨论】:

谢谢。这不会产生烦人的outlook 错误消息吗? 它可能会在较新版本的 Windows 上触发验证。不知道你会如何抑制它。我不再运行 Windows。【参考方案5】:

我想使用 SMTPLIB 发送电子邮件,它更容易并且不需要本地设置。在其他答案没有直接帮助之后,这就是我所做的。

在浏览器中打开 Outlook;转到右上角,单击设置的齿轮图标,从出现的下拉列表中选择“选项”。 转到“帐户”,单击“Pop 和 Imap”, 您将看到选项:“让设备和应用程序使用 pop”,

选择是选项并保存更改。

这是后面的代码;必要时进行编辑。 最重要的是启用POP和这里的服务器代码;

import smtplib

body = 'Subject: Subject Here .\nDear ContactName, \n\n' + 'Email\'s BODY text' + '\nYour :: Signature/Innitials'
try:
    smtpObj = smtplib.SMTP('smtp-mail.outlook.com', 587)
except Exception as e:
    print(e)
    smtpObj = smtplib.SMTP_SSL('smtp-mail.outlook.com', 465)
#type(smtpObj) 
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('me@outlook.com', "password") 
smtpObj.sendmail('sender@outlook.com', 'recipient@gmail.com', body) # Or recipient@outlook

smtpObj.quit()
pass

【讨论】:

这个方法也适用于 smtp.office365.com 的那些想知道的人。【参考方案6】:

最简单的 OFFICE 365 解决方案:

from O365 import Message

html_template =     """ 
            <html>
            <head>
                <title></title>
            </head>
            <body>
                    
            </body>
            </html>
        """

final_html_data = html_template.format(df.to_html(index=False))

o365_auth = ('sender_username@company_email.com','Password')
m = Message(auth=o365_auth)
m.setRecipients('receiver_username@company_email.com')
m.setSubject('Weekly report')
m.setBodyHTML(final)
m.sendMessage()

这里的df是转换成html Table的dataframe,正在注入到html_template

【讨论】:

【参考方案7】:

除了win32,如果你的公司已经为你设置了web outlook,你也可以试试微软官方制作的PYTHON REST API。 (https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations)

【讨论】:

【参考方案8】:

这是我尝试使用 Win32 的一个:

import win32com.client as win32
import psutil
import os
import subprocess
import sys

# Drafting and sending email notification to senders. You can add other senders' email in the list
def send_notification():


    outlook = win32.Dispatch('outlook.application')
    olFormatHTML = 2
    olFormatPlain = 1
    olFormatRichText = 3
    olFormatUnspecified = 0
    olMailItem = 0x0

    newMail = outlook.CreateItem(olMailItem)
    newMail.Subject = sys.argv[1]
    #newMail.Subject = "check"
    newMail.BodyFormat = olFormatHTML    #or olFormatRichText or olFormatPlain
    #newMail.HTMLBody = "test"
    newMail.HTMLBody = sys.argv[2]
    newMail.To = "xyz@abc.com"
    attachment1 = sys.argv[3]
    attachment2 = sys.argv[4]
    newMail.Attachments.Add(attachment1)
    newMail.Attachments.Add(attachment2)

    newMail.display()
    # or just use this instead of .display() if you want to send immediately
    newMail.Send()





# Open Outlook.exe. Path may vary according to system config
# Please check the path to .exe file and update below
def open_outlook():
    try:
        subprocess.call(['C:\Program Files\Microsoft Office\Office15\Outlook.exe'])
        os.system("C:\Program Files\Microsoft Office\Office15\Outlook.exe");
    except:
        print("Outlook didn't open successfully")     
#

# Checking if outlook is already opened. If not, open Outlook.exe and send email
for item in psutil.pids():
    p = psutil.Process(item)
    if p.name() == "OUTLOOK.EXE":
        flag = 1
        break
    else:
        flag = 0

if (flag == 1):
    send_notification()
else:
    open_outlook()
    send_notification()

【讨论】:

以上是关于通过 Python 发送 Outlook 电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

Python Post 请求 - 通过 Outlook API 发送文件时出现 415 错误

Python Outlook发送邮件

用python调用outlook发邮件的问题

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

使用 Python 从 Outlook 发送电子邮件不起作用

c#代码怎么通过outlook发邮件