368 Stimmen

Wie sende ich E-Mail-Anhänge?

Ich habe Probleme, zu verstehen, wie man eine Anlage mit Python per E-Mail versendet. Ich habe erfolgreich einfache Nachrichten mit dem smtplib verschickt. Könnte mir bitte jemand erklären, wie man eine Anlage in einer E-Mail versendet. Ich weiß, dass es andere Beiträge online gibt, aber als Python-Anfänger fällt es mir schwer, sie zu verstehen.

6 Stimmen

Hier ist eine einfache Implementierung, die mehrere Dateien anhängen kann und sogar in Bezug auf Bilder eingebettet werden kann. datamakessense.com/…

0 Stimmen

Ich fand das nützlich drupal.org/project/mimemail/issues/911612 stellt sich heraus, dass Bilddateianhänge an einen damit verbundenen Typ-Kindteil angehängt werden müssen. Wenn Sie das Bild an den Wurzel-MIME-Teil anhängen, können die Bilder in der Liste der angehängten Elemente angezeigt und in Clienten wie Outlook365 vorab angezeigt werden.

2voto

sdoshi Punkte 31
von E-Mail.mime.text importieren MIMEText
von E-Mail.mime.multipart importieren MIMEMultipart
importiere smtplib
import mimetypes
importiere E-Mail.mime.application

smtp_ssl_host = 'smtp.gmail.com'  # smtp.mail.yahoo.com
smtp_ssl_port = 465
s = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
s.anmeldung(email_user, email_pass)

msg = MIMEMultipart()
msg['Betreff'] = 'Ich habe ein Bild'
msg['Von'] = email_user
msg['An'] = email_user

txt = MIMEText('Ich habe gerade eine neue Kamera gekauft.')
msg.attach(txt)

filename = 'einführung-in-algorithmen-3-auflage-sep-2010.pdf' #Pfad zur Datei
fo = öffnen(filename, 'rb')
anhängen = E-Mail.mime.application.MIMEApplication(fo.read(), _subtype="pdf")
fo.close()
anhängen.add_header('Inhalt-Disposition', 'Anhang', filename=filename)
msg.attach(anhängen)
s.sende_nachricht(msg)
s.quit()

Für eine Erklärung kannst du diesen Link verwenden, er erklärt es richtig https://medium.com/@sdoshi579/to-send-an-email-along-with-attachment-using-smtp-7852e77623

2voto

Abdul Haseeb Punkte 29
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
import smtplib

msg = MIMEMultipart()

password = "Passwort"
msg['From'] = "Absenderadresse"
msg['To'] = "Empfängeradresse"
msg['Subject'] = "Angehängtes Foto"
msg.attach(MIMEImage(file("abc.jpg").read()))
file = "Dateipfad"
fp = open(file, 'rb')
img = MIMEImage(fp.read())
fp.close()
msg.attach(img)
server = smtplib.SMTP('smtp.gmail.com: 587')
server.starttls()
server.login(msg['From'], password)
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()

4 Stimmen

Hi, Willkommen, Bitte immer eine Erklärung Ihrer Antwort posten, wenn Sie eine Frage beantworten, um ein besseres Verständnis zu gewährleisten.

1voto

Alex Potapenko Punkte 156

Keine der derzeit gegebenen Antworten hier werden korrekt mit Nicht-ASCII-Symbolen in Dateinamen mit Clients wie GMail, Outlook 2016 und anderen funktionieren, die RFC 2231 nicht unterstützen (siehe hier). Der untenstehende Python 3-Code ist angepasst von einigen anderen stackoverflow-Antworten (sorry, die Ursprungslinks nicht gespeichert) und odoo/openerp-Code für Python 2.7 (siehe ir_mail_server.py). Es funktioniert korrekt mit GMail und anderen und verwendet auch SSL.

import smtplib, ssl
from os.path import basename
from email.mime.base import MIMEBase
from mimetypes import guess_type
from email.encoders import encode_base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email.charset import Charset

def try_coerce_ascii(string_utf8):
    """Versucht den gegebenen UTF-8-kodierten String als ASCII zu dekodieren,
       nachdem er es in UTF-8 umgewandelt hat, und gibt dann den bestätigten 7-Bit-ASCII-String zurück.

       Falls der Prozess fehlschlägt (weil der String
       Nicht-ASCII-Zeichen enthält), wird ``None`` zurückgegeben.
    """
    try:
        string_utf8.encode('ascii')
    except UnicodeEncodeError:
        return
    return string_utf8

def encode_header_param(param_text):
    """Gibt eine geeignete nach RFC 2047 enkodierte Darstellung des gegebenen
       Header-Parameterwerts zurück, die zur direkten Zuweisung als Wert
       des Parameters (z.B. über Message.set_param() oder Message.add_header())
       geeignet ist. RFC 2822 geht davon aus, dass Header nur 7-Bit-Zeichen enthalten,
       daher stellen wir sicher, dass dies der Fall ist, indem wir bei Bedarf eine RFC 2047-Kodierung verwenden.

       :param param_text: Unicode- oder UTF-8-kodierter String mit Header-Wert
       :rtype: string
       :return: wenn ``param_text`` eine reine ASCII-Zeichenkette darstellt,
                wird dieselbe 7-Bit-Zeichenkette zurückgegeben, sonst wird eine
                ASCII-Zeichenkette zurückgegeben, die den RFC2047-enkodierten Text enthält.
    """
    if not param_text: return ""
    param_text_ascii = try_coerce_ascii(param_text)
    return param_text_ascii if param_text_ascii\
         else Charset('utf8').header_encode(param_text)

smtp_server = ''
smtp_port = 465  # Standardport für SSL
sender_email = ''
sender_password = ''
receiver_emails = ['', '']
subject = 'Testnachricht'
message = """\
Hallo! Dies ist eine Testnachricht mit Anhängen.

Diese Nachricht wird von Python gesendet."""

files = ['/1.pdf', '/2.png']

# Erzeugt einen sicheren SSL-Kontext
context = ssl.create_default_context()

msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = COMMASPACE.join(receiver_emails)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject

msg.attach(MIMEText(message))

for f in files:
    mimetype, _ = guess_type(f)
    mimetype = mimetype.split('/', 1)
    with open(f, "rb") as fil:
        part = MIMEBase(mimetype[0], mimetype[1])
        part.set_payload(fil.read())
        encode_base64(part)
    filename_rfc2047 = encode_header_param(basename(f))

    # Die standardmäßige RFC 2231-Kodierung von Message.add_header() funktioniert in Thunderbird, aber nicht in GMail
    # daher beheben wir es, indem wir anstelle dessen die Dateinamen mit RFC 2047 kodieren.
    part.set_param('name', filename_rfc2047)
    part.add_header('Content-Disposition', 'attachment', filename=filename_rfc2047)
    msg.attach(part)

with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:
    server.login(sender_email, sender_password)
    server.sendmail(sender_email, receiver_emails, msg.as_string())

0 Stimmen

Ich habe mich für diese Version entschieden. Speziell wegen der Dateinamen, die in meinem Fall Nicht-ASCII-Zeichen enthalten können.

0 Stimmen

Die aktualisierte E-Mail-Bibliothek in Python 3.6+ ist wesentlich transparenter und robuster bei diesen Dingen. Sie sollte sich um die meisten dieser Details ohne Ihr Zutun kümmern; dies ist einer der Hauptgründe und recht zwingenden Gründe, von der älteren API, die Sie hier noch verwenden, zu migrieren.

0voto

TonyRyan Punkte 138

Im Folgenden finden Sie eine Kombination dessen, was ich aus SoccerPlayers Beitrag Hier und folgendem Link gefunden habe, der es mir erleichtert hat, eine xlsx-Datei anzuhängen. Hier gefunden

file = 'File.xlsx'
username=''
password=''
send_from = ''
send_to = 'Empfänger1 , Empfänger2'
Cc = 'Empfänger'
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = send_to
msg['Cc'] = Cc
msg['Date'] = formatdate(localtime = True)
msg['Subject'] = ''
server = smtplib.SMTP('smtp.gmail.com')
port = '587'
fp = open(file, 'rb')
part = MIMEBase('application','vnd.ms-excel')
part.set_payload(fp.read())
fp.close()
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename='Name der Datei hier')
msg.attach(part)
smtp = smtplib.SMTP('smtp.gmail.com')
smtp.ehlo()
smtp.starttls()
smtp.login(username,password)
smtp.sendmail(send_from, send_to.split(',') + msg['Cc'].split(','), msg.as_string())
smtp.quit()

0voto

John Rua Punkte 1

Mit meinem Code können Sie E-Mail-Anhänge über Gmail senden, Sie müssen:

Ihre Gmail-Adresse bei ___IHRE SMTP E-MAIL HIER___ einstellen
Legen Sie Ihr Gmail-Konto Passwort bei __IHREN SMTP-PASSWORT HIER___ fest
Im Teil ___E-MAIL ZUM EMPFANGEN DER NACHRICHT___ müssen Sie die Ziel-E-Mail-Adresse einstellen.
Alarmbenachrichtigung ist der Betreff.
Jemand ist in den Raum gekommen, Bild angehängt ist der Text.
["/home/pi/webcam.jpg"] ist ein Bildanhänger.

Hier ist der vollständige Code:

#!/usr/bin/env python
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import os

BENUTZERNAME = "___IHRE SMTP EMAIL HIER___"
PASSWORT = "__IHREN SMTP-PASSWORT HIER___"

def sendMail(to, subject, text, files=[]):
    assert type(to)==list
    assert type(files)==list

    msg = MIMEMultipart()
    msg['From'] = BENUTZERNAME
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for file in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(file,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % os.path.basename(file))
        msg.attach(part)

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo_or_helo_if_needed()
    server.starttls()
    server.ehlo_or_helo_if_needed()
    server.login(BENUTZERNAME,PASSWORT)
    server.sendmail(BENUTZERNAME, to, msg.as_string())
    server.quit()

sendMail( ["___E-MAIL ZUM EMPFANGEN DER NACHRICHT___"],
        "Alarmbenachrichtigung",
        "Jemand ist in den Raum gekommen, Bild angehängt",
        ["/home/pi/webcam.jpg"] )

0 Stimmen

Lange nichts gesehen! Gut zu sehen, dass du deinen Code ordnungsgemäß zuordnest und ihn direkt in die Antwort einschließt. Es ist jedoch im Allgemeinen nicht gern gesehen, denselben Antwortcode auf mehreren Fragen zu kopieren und einzufügen. Wenn sie wirklich mit derselben Lösung gelöst werden können, solltest du die Fragen stattdessen als Duplikate markieren.

0 Stimmen

Ich würde server.sendmail() vermeiden und stattdessen server.send_message(msg) verwenden. Erstens ist es einfacher und zweitens habe ich Probleme mit der sendmail-Funktion entdeckt, die ich nicht erklären kann.

0 Stimmen

@TimothyC.Quinn Aber dafür müssten Sie endlich auf die EmailMessage API aktualisieren, anstatt bei dieser alten Python 3.5 Legacy-API zu bleiben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X