【问题标题】:How to send output from a python script to an email address如何将 python 脚本的输出发送到电子邮件地址
【发布时间】:2011-07-11 23:37:18
【问题描述】:

我有一个线程化的 python 脚本,它可以 ping 局域网上的 20 个节点,并打印出每个节点的状态:节点处于活动状态、节点处于关闭状态等。 我想将此输出发送到我的电子邮件帐户,因为我打算让这个脚本每周运行一次,它自己,如果我物理上远离局域网,我不必担心,我可以请查看我的电子邮件。

语言:Python。操作系统:Linux Mint 10 朱莉娅。谢谢

【问题讨论】:

  • 您使用什么电子邮件服务提供商? Gmail、Outlook、雅虎?
  • 不,提供了附加信息。投反对票。

标签: python email scripting smtp


【解决方案1】:

如果它每周运行一次,您可能会从 crontab 中运行它?

30 2 * * 5  python yourScript.py | mail -s outputFromScript your@email.address

【讨论】:

  • 您可能希望将它(使用“|”)通过管道传输到邮件中,而不是重定向到一个名为带有空格的文件(具体取决于 cron 解析命令行的方式),除了它是理智和明智的想法。
  • @Vatine - 你对管道绝对正确,谢谢,修复!
  • 酷,我的 +1 已经给了,但我给你一个评论,因为你编辑得这么快。
  • @eumiro 假设我有一个简单的 MRSS feedparser 脚本,每小时运行一次,我需要在 Crontab 中为“outputFromScript”输入什么?
【解决方案2】:

使用smtplib。他们提供的example 非常好。

import smtplib

def prompt(prompt):
    return raw_input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print "Enter message, end with ^D (Unix) or ^Z (Windows):"

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))
while True:
    try:
        line = raw_input()
    except EOFError:
        break
    if not line:
        break
    msg += line

print "Message length is " + repr(len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

【讨论】:

  • 什么是raw_input?我所拥有的是一个运行大量打印语句的脚本。脚本完成后,我想使用我的 smtplib 代码通过电子邮件发送它打印的所有内容。这不起作用。
  • 你为什么不用sys.stdout
  • @Pinocchio 你能把那些打印语句改成记录器语句吗?
  • @C.Lewis 那是什么?
  • @Pinocchio 我认为最好放一些代码示例(或创建一个新问题..)
【解决方案3】:

看看 logging 和 logging.config,我以前用它来接收来自后台运行的脚本的错误消息

http://docs.python.org/library/logging.html

例如

import logging
import logging.config

logDir = "./logs/"

logging.config.fileConfig(logDir+'logging.conf')
logger = logging.getLogger('email')

logger.debug('THIS IS A DEBUG MESSAGE')
logger.error('THIS IS AN ERROR')

然后是 logging.conf

[loggers]
keys=root,email

[logger_root]
level=DEBUG
handlers=rotatingFileHandler

[logger_email]
level=ERROR
handlers=email
qualname=email

[formatters]
keys=emailFormatter,rotatingFormatter

[formatter_emailFormatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s

[formatter_rotatingFormatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
datefmt=%m-%d %H:%M

[handlers]
keys=email,rotatingFileHandler

[handler_email]
class=handlers.SMTPHandler
level=ERROR
formatter=emailFormatter
args=('mail.xxx','x@x.com',['y@y.com',],'ERROR!',('x@x.com','xxx'))

[handler_rotatingFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=rotatingFormatter
args=('./logs/log.out', 'maxBytes=1000000', 'backupCount=5')

从上面我会在我的电子邮件中收到“这是一个错误”。

【讨论】:

    【解决方案4】:

    您可以使用 logger 打印到 stout 和记录器,而不是使用主要的 print 输出

    您可以根据Logging Cookbook设置如下记录器:

    import logging
    log_file = r'C:\Users\user\Downloads\LogFileName.log'
    
    logger = logging.getLogger('simple_example')
    logger.setLevel(logging.INFO)
    
    # create file handler which logs even debug messages
    fh = logging.FileHandler('log_file')
    fh.setLevel(logging.DEBUG)
    # create console handler with a higher log level
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    # create formatter and add it to the handlers
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
    # add the handlers to logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    
    

    现在用logger.info替换脚本中的print

    之前的例子:

    print("Printing status")
    

    之后的示例:

    logger.info("Printing status")
    

    然后您可以将日志通过电子邮件发送给自己,如下所示:

    import smtplib
    from email.message import EmailMessage
    import os
    msg_body = "Body Text"
    
    msg = EmailMessage()
    
    msg['Subject'] = "Subject"
    msg['From'] = "send_from@email.com"
    msg['To'] = "send_to@email.com"
    
    msg.set_content(msg_body)
    
    if os.path.isfile(log_file):
            msg.add_attachment(open(log_file, "r").read(), filename=os.path.basename(log_file))
    
    
    # Send the message via our own SMTP server.
    s = smtplib.SMTP("smtpa.server")
    s.send_message(msg)
    s.quit()
    

    【讨论】:

    • 我也可以用一个命令打印和记录吗?就像这样做会让我失去向终端显示的能力?
    • 当然。完全没问题
    【解决方案5】:

    关于使用 Python 发送电子邮件主题的一个很好的资源是 Al Sweigart 的“使用 Python 自动化无聊的东西”。 Chapter 18 是您想要的部分。简而言之,如果你有一个大型电子邮件提供商(想想 Google、Outlook、Yahoo 等)的电子邮件地址,你可以使用他们的简单邮件传输协议 (SMTP) 服务器来处理来自 Python 的邮件。正如艾尔所说:

    如果您没有与大型提供商之一的电子邮件地址,或者您无法使用外部提供商的电子邮件地址,那就有点困难了。也许您公司的某个人可以告诉您 1)您的公司是否有 SMTP 服务器以及 2)它的域名和端口号是什么。

    一旦你拥有了所有这些,从你的程序中发送一封电子邮件就是小菜一碟:

    import smtplib
    
    def main():
    
        # get message from node
        message1 = 'Node 1 is up :)'
        # print message from node
        print(message1)
        # get message from another node
        message2 = 'Node 2 is down :('
        # print that too
        print(message2)
    
        # now, all done talking to nodes.
        # time to compile node response results and send an email.
    
        # first, let's get every thing setup for the email
        from_me = 'awesome.name@my_email_provider.com'
        to_me = 'awesome.name@my_email_provider.com'
        email_message = message1 + '\n' + message2
    
        # second, let's make sure we have a connection to a Simple Mail Transfer Protocol (SMTP) server 
        # this server will receive and then send out our email message
        domain_name = 'smtp.my_email_provider.com'
        port_number = 587  # or maybe, 465
        server = smtplib.SMTP(domain_name, port_number)
    
        # alright! if that last line didn't raise an exceptions, then you're good to go. Send that bad boy off.
        server.sendmail(from_me, to_me, email_message)
    
    if __name__ == '__main__':
        main()
    

    记录器也很棒,所以不要低估每个人对它们的评价。 打印到终端。记录到文件。并通过电子邮件发送!记录器可以做任何事情。

    【讨论】:

    • 你将如何记录所有的消息?如果他们有 20 个节点,你会建议他们有 message1message20 并将它们全部写到电子邮件中,如下所示:email_message = message1 + '\n' + message2+ '\n' + message3 + '\n' + message4 + '\n' + message5 等?
    • 没有。我不建议这样做。该代码旨在作为一个玩具示例,重点介绍如何从 Python 发送电子邮件。至少,用于存储和编译消息的列表和join 调用似乎是合理的。但实际上,您使用记录器的解决方案肯定更加强大和通用。
    【解决方案6】:

    您需要一个 SMTP 服务器来发送电子邮件。查看smtplib for Python

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多