簡體   English   中英

utf-8郵箱怎么發?

[英]How to send utf-8 e-mail?

請問如何發送utf8郵件?

import sys
import smtplib
import email
import re

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

def sendmail(firm, fromEmail, to, template, subject, date):
    with open(template, encoding="utf-8") as template_file:
        message = template_file.read()

    message = re.sub(r"{{\s*firm\s*}}", firm, message)
    message = re.sub(r"{{\s*date\s*}}", date, message)
    message = re.sub(r"{{\s*from\s*}}", fromEmail, message)
    message = re.sub(r"{{\s*to\s*}}", to, message)
    message = re.sub(r"{{\s*subject\s*}}", subject, message)

    msg = MIMEMultipart("alternative")
    msg.set_charset("utf-8")
    
    msg["Subject"] = subject
    msg["From"] = fromEmail
    msg["To"] = to

    #Read from template
    html = message[message.find("html:") + len("html:"):message.find("text:")].strip()
    text = message[message.find("text:") + len("text:"):].strip()

    part1 = MIMEText(html, "html")
    part2 = MIMEText(text, "plain")
    
    msg.attach(part1)    
    msg.attach(part2)

    try:
        server = smtplib.SMTP("10.0.0.5")
        server.sendmail(fromEmail, [to], msg.as_string())
        return 0
    except Exception as ex:
        #log error
        #return -1
        #debug
        raise ex
    finally:
        server.quit()

if __name__ == "__main__":
    #debug
    sys.argv.append("Moje")
    sys.argv.append("newsletter@example.cz")
    sys.argv.append("subscriber@example.com")
    sys.argv.append("may2011.template")
    sys.argv.append("This is subject")
    sys.argv.append("This is date")

    
    if len(sys.argv) != 7:
        exit(-2)

    firm = sys.argv[1]
    fromEmail = sys.argv[2]
    to = sys.argv[3]
    template = sys.argv[4]
    subject = sys.argv[5]
    date = sys.argv[6]
    
    exit(sendmail(firm, fromEmail, to, template, subject, date))

Output

Traceback (most recent call last):
  File "C:\Documents and Settings\Administrator\Plocha\Newsletter-build-desktop\sendmail.py", line 69, in <module>
    exit(sendmail(firm, fromEmail, to, template, subject, date))   
  File "C:\Documents and Settings\Administrator\Plocha\Newsletter-build-desktop\sendmail.py", line 45, in sendmail
    raise ex
  File "C:\Documents and Settings\Administrator\Plocha\Newsletter-build-desktop\sendmail.py", line 39, in sendmail
    server.sendmail(fromEmail, [to], msg.as_string())
  File "C:\Python32\lib\smtplib.py", line 716, in sendmail
    msg = _fix_eols(msg).encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode character '\u011b' in position 385: ordinal not in range(128)

您只需要在MIMEText調用中添加'utf-8'參數(默認情況下就假定為'us-ascii' )。

例如:

# -*- encoding: utf-8 -*-

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

msg = MIMEMultipart("alternative")
msg["Subject"] = u'テストメール'
part1 = MIMEText(u'\u3053\u3093\u306b\u3061\u306f\u3001\u4e16\u754c\uff01\n',
                 "plain", "utf-8")
msg.attach(part1)

print msg.as_string().encode('ascii')

這里的先前答案足以適用於Python 2及更早版本的Python 3.從Python 3.6開始,新代碼通常應使用現代電子郵件Message EmailMessage ,而不是舊的email.message.Message MIMEText MIMEMultipart 較新的 API 已在 Python 3.3 中非正式引入,因此不再需要舊版本,除非您需要可移植回 Python 2(或 3.2,反正沒有人會想要)。

使用新的 API,您不再需要從部分手動組裝顯式 MIME 結構,或顯式 select 正文部分編碼等。Unicode 也不再是特例; email庫將透明地為常規文本 select 提供合適的容器類型和編碼。

import sys
import re
import smtplib
from email.message import EmailMessage

def sendmail(firm, fromEmail, to, template, subject, date):
    with open(template, "r", encoding="utf-8") as template_file:
        message = template_file.read()

    message = re.sub(r"{{\s*firm\s*}}", firm, message)
    message = re.sub(r"{{\s*date\s*}}", date, message)
    message = re.sub(r"{{\s*from\s*}}", fromEmail, message)
    message = re.sub(r"{{\s*to\s*}}", to, message)
    message = re.sub(r"{{\s*subject\s*}}", subject, message)

    msg = EmailMessage()    
    msg["Subject"] = subject
    msg["From"] = fromEmail
    msg["To"] = to

    html = message[message.find("html:") + len("html:"):message.find("text:")].strip()
    text = message[message.find("text:") + len("text:"):].strip()

    msg.set_content(text)
    msg.add_alternative(html, subtype="html")

    try:
        server = smtplib.SMTP("10.0.0.5")
        server.send_message(msg)
        return 0
    # XXX FIXME: useless
    except Exception as ex:
        raise ex
    finally:
        server.quit()
        # Explicitly return error
        return 1

if __name__ == "__main__":
    if len(sys.argv) != 7:
        # Can't return negative
        exit(2)

    exit(sendmail(*sys.argv[1:]))

我不確定我是否完全理解此處的模板處理。 即使需求略有不同的從業者也應該查看Python email示例文檔,其中包含幾個關於如何實現常見 email 用例的簡單示例。

毯子except在這里顯然是多余的,但我把它留作占位符,以防你想看看如果你有一些有用的東西放在那兒,異常處理會是什么樣子。

也許還注意到smtplib允許您with SMTP("10.9.8.76") as server: with a context manager 說。

MartinDrlík提出的問題已經7年零8個月了……如今,由於Python的開發人員的幫助,使用Python的第3版解決了編碼問題。

因此,不再需要指定必須使用utf-8編碼:

#!/usr/bin/python2
# -*- encoding: utf-8 -*-
...
    part2 = MIMEText(text, "plain", "utf-8")

我們將簡單地寫:

#!/usr/bin/python3
...
    part2 = MIMEText(text, "plain")

最終結果:MartinDrlík的腳本運行良好!

但是,最好按照email:示例中的建議使用email.parser模塊。

對於可能感興趣的人,我編寫了一個使用 SMTPlib 的 Mailer 庫,並處理標頭、ssl/tls 安全性、附件和批量 email 發送。

當然它也處理 UTF-8 主題和正文的郵件編碼。

您可以在以下位置找到代碼: https://github.com.netinvent/ofunctions/blob/master/ofunctions/mailer/__init__.py

相關的編碼部分是

message["Subject"] = Header(subject, 'utf-8')
message.attach(MIMEText(body, "plain", 'utf-8'))

TL;DR:安裝pip install ofunctions.mailer

用法:

from ofunctions.mailer import Mailer

mailer = Mailer(smtp_server='myserver', smtp_port=587)
mailer.send_email(sender_mail='me@example.com', recipient_mails=['them@example.com', 'otherguy@example.com'])

編碼已設置為 UTF-8,但您可以使用mailer = Mailer(smtp_srever='...', encoding='latin1')將編碼更改為您需要的任何編碼

在我公司,我們使用下一個代碼

import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

...

msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = from_addr
msg['To'] = to_addr
msg.attach(MIMEText(html, 'html', 'utf-8'))  
# or you can use 
# msg.attach(MIMEText(text, 'plain', 'utf-8')

server = smtplib.SMTP('localhost')
server.sendmail(msg['From'], [msg['To']], msg.as_string())
server.quit()

我使用標准包做到了: sslsmtplibemail

import configparser
import smtplib
import ssl
from email.message import EmailMessage

# define bcc:[str], cc: [str], from_email: str, to_email: str, subject: str, html_body: str, str_body: str
... 

# save your login and server information in a settings.ini file
cfg.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), "settings.ini"))

msg = EmailMessage()
msg['Bcc'] = ", ".join(bcc)
msg['Cc'] = ", ".join(cc)
msg['From'] = from_email
msg['To'] = to_email
msg['Subject'] = subject

msg.set_content(str_body)
msg.add_alternative(html_body, subtype="html")

# add SSL (layer of security)
context = ssl.create_default_context()

# log in and send the email
with smtplib.SMTP_SSL(cfg.get("mail", "server"), cfg.getint("mail", "port"), context=context) as smtp:
    smtp.login(cfg.get("mail", "username"), cfg.get("mail", "password"))
    smtp.send_message(msg=msg)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM