Как отправить вывод из скрипта Python на адрес электронной почты

У меня есть многопоточный скрипт Python, который пингует 20 узлов в локальной сети и выводит статус каждого: узел активен, узел отключен и т. д. Я хотел бы, чтобы этот вывод был отправлен на мою учетную запись электронной почты, потому что я намерен заставить этот скрипт запускаться один раз в неделю, сам по себе, и если я физически нахожусь вдали от локальной сети, мне не о чем беспокоиться, я могу просто проверить свою электронную почту.

Язык:ПИТОН. ОС: Linux Mint 10 Юлия. Спасибо


person Samuel    schedule 09.03.2011    source источник
comment
Каким поставщиком услуг электронной почты вы пользуетесь? Gmail, Outlook, Yahoo?   -  person Steve    schedule 12.04.2020
comment
Нет, предоставляется дополнительная информация. Проголосовал вниз.   -  person Ozgur Bagci    schedule 12.04.2020


Ответы (6)


Если он запускается раз в неделю, вы, вероятно, будете запускать его из crontab?

30 2 * * 5  python yourScript.py | mail -s outputFromScript [email protected]
person eumiro    schedule 09.03.2011
comment
Вы, вероятно, захотите направить его (используя |) в почту, а не перенаправлять в файл с именем что-то с пробелами (в зависимости от того, как cron анализирует командную строку), кроме того, что это разумная и разумная идея. - person Vatine; 09.03.2011
comment
@Vatine - вы абсолютно правы с трубой, спасибо, исправлено! - person eumiro; 09.03.2011
comment
Круто, мой +1 уже дан, но я даю вам один за ваш комментарий за то, что вы так быстро отредактировали. - person Vatine; 09.03.2011
comment
@eumiro Допустим, у меня есть простой скрипт MRSS feedparser, который запускается каждый час, что мне нужно ввести там для outputFromScript в Crontab? - person AdjunctProfessorFalcon; 24.07.2015

Используйте smtplib. Приведенный ими пример довольно хорош.

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()
person chmullig    schedule 09.03.2011
comment
Что такое raw_input? У меня есть сценарий, работающий с большим количеством операторов печати. После завершения сценария я хочу отправить все, что он напечатал, по электронной почте, используя мой код smtplib. Это не работает. - person Charlie Parker; 06.04.2020
comment
почему вы не используете sys.stdout? - person Charlie Parker; 07.04.2020
comment
@Pinocchio, вы можете изменить эти операторы печати на операторы регистратора? - person C. Fennell; 08.04.2020
comment
@ К.Льюис, что это? - person Charlie Parker; 08.04.2020
comment
@Pinocchio Я думаю, будет лучше, если вы разместите пример кода (или создадите новый вопрос ..) - person Chen A.; 09.04.2020

Взгляните на 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','[email protected]',['[email protected]',],'ERROR!',('[email protected]','xxx'))

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

Из вышесказанного я получу сообщение «ЭТО ОШИБКА» по ​​электронной почте.

person PDStat    schedule 09.03.2011

Вместо основного print вывода вы можете использовать logger для печати на стауте и в регистраторе.

Вы можете настроить регистратор следующим образом в соответствии с Пособием по ведению журналов:

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)

Теперь замените print в вашем скрипте на logger.info

Пример до:

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'] = "[email protected]"
msg['To'] = "[email protected]"

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()
person C. Fennell    schedule 07.04.2020
comment
Могу ли я также распечатать журнал AND с помощью одной команды? Например, это лишит меня возможности отображать на терминале? - person Charlie Parker; 08.04.2020
comment
Определенно. Нет никаких проблем - person C. Fennell; 08.04.2020

Отличным ресурсом по теме отправки электронной почты с помощью Python является книга Эла Свейгарта «Автоматизация скучных вещей с помощью Python». Глава 18 — это та часть, которая вам нужна. Короче говоря, если у вас есть адрес электронной почты одного из крупных провайдеров электронной почты (например, Google, Outlook, Yahoo и т. д.), вы можете использовать их сервер (серверы) Simple Mail Transfer Protocol (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()

Лесорубы тоже хороши, так что не сбрасывайте со счетов то, что все говорят о них. Распечатать на терминал. Войти в файл. И отправить по электронной почте! Лесорубы могут все.

person Steve    schedule 12.04.2020
comment
Как бы вы записали все сообщения? Если у них есть 20 узлов, вы бы предложили им иметь от message1 до message20 и написать их все по электронной почте, например: email_message = message1 + '\n' + message2+ '\n' + message3 + '\n' + message4 + '\n' + message5 и т. д.? - person C. Fennell; 13.04.2020
comment
Нет. Я бы не рекомендовал это. Код был задуман как игрушечный пример с упором на то, как отправить электронное письмо из Python. По крайней мере, список и join вызов для хранения и компиляции сообщений кажутся разумными. Но на самом деле ваше решение с использованием регистратора, безусловно, более надежное и универсальное. - person Steve; 14.04.2020

Вам нужен SMTP-сервер для отправки электронной почты. Ознакомьтесь с smtplib для Python.

person Philippe Lavoie    schedule 09.03.2011