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())
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.