如何发送utf-8电子邮件?

发布于 2024-11-05 18:37:16 字数 2932 浏览 1 评论 0原文

请问如何发送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("[email protected]")
    sys.argv.append("[email protected]")
    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))

输出

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)

how to send utf8 e-mail please?

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("[email protected]")
    sys.argv.append("[email protected]")
    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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

撩人痒 2024-11-12 18:37:16

您只需将 'utf-8' 参数添加到 MIMEText 调用中(默认情况下假定为 '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')

You should just add 'utf-8' argument to your MIMEText calls (it assumes 'us-ascii' by default).

For example:

# -*- 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')
意中人 2024-11-12 18:37:16

Martin Drlí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")

最终结果:Martin Drlík 的脚本运行得非常好!

但是,最好使用 email.parser 模块,如 email 中的建议:示例

The question asked by Martin Drlík is 7 years and 8 months old... And nowadays, thanks to the developers of Python, encoding problems are solved with version 3 of Python.

Consequently, it is no longer necessary to specify that one must use the utf-8 encoding:

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

We will simply write:

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

Ultimate consequence: Martin Drlík's script works perfectly well!

However, it would be better to use the email.parser module, as suggested in email: Examples.

疧_╮線 2024-11-12 18:37:16

这里之前的答案对于 Python 2 和早期版本的 Python 3 来说已经足够了。从 Python 3.6 开始,新代码通常应该使用现代的 EmailMessage API,而不是旧的 email.message.Message< /code> 类或相关的 MIMEMultipartMIMEText 等类。新的 API 已在 Python 3.3 中非正式引入,因此旧的 API 应该不再是必要的,除非您需要可移植回 Python 2(或 3.2,无论如何,任何头脑正常的人都不会想要)。

使用新的 API,您不再需要手动从各部分组装显式 MIME 结构,或显式选择正文部分编码等。Unicode 也不再是特殊情况; email 库将透明地为常规文本选择合适的容器类型和编码。

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 电子邮件 示例文档
其中包含如何实现常见电子邮件用例的几个简单示例。

毯子 except 在这里显然是多余的,但我将它作为占位符保留下来,以防您想查看异常处理可能是什么样子,如果您有一些有用的东西可以放在那里。

也许还请注意,smtplib 允许您使用上下文管理器说with SMTP("10.9.8.76") as server:

The previous answers here were adequate for Python 2 and earlier versions of Python 3. Starting with Python 3.6, new code should generally use the modern EmailMessage API rather than the old email.message.Message class or the related MIMEMultipart, MIMEText etc classes. The newer API was unofficially introduced already in Python 3.3, and so the old one should no longer be necessary unless you need portability back to Python 2 (or 3.2, which nobody in their right mind would want anyway).

With the new API, you no longer need to manually assemble an explicit MIME structure from parts, or explicitly select body-part encodings etc. Nor is Unicode a special case any longer; the email library will transparently select a suitable container type and encoding for regular text.

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:]))

I'm not sure I completely understand the template handling here. Practitioners with even slightly different needs should probably instead review the Python email examples documentation
which contains several simple examples of how to implement common email use cases.

The blanket except is clearly superfluous here, but I left it in as a placeholder in case you want to see what exception handling might look like if you had something useful to put there.

Perhaps notice also that smtplib allows you to say with SMTP("10.9.8.76") as server: with a context manager.

2024-11-12 18:37:16

在我的公司,我们使用下一个代码

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

In my company we use next code

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()
似最初 2024-11-12 18:37:16

对于可能感兴趣的人,我编写了一个使用 SMTPlib 的 Mailer 库,并处理标头、ssl/tls 安全性、附件和批量电子邮件发送。

当然,它还处理主题和正文的 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='[email protected]', recipient_mails=['[email protected]', '[email protected]'])

编码已设置为 UTF-8,但您可以使用 mailer = Mailer(smtp_srever='...',encoding='latin1') 将编码更改为您需要的任何编码

For whom it might interest, I've written a Mailer library that uses SMTPlib, and deals with headers, ssl/tls security, attachments and bulk email sending.

Of course it also deals with UTF-8 mail encoding for subject and body.

You may find the code at: https://github.com/netinvent/ofunctions/blob/master/ofunctions/mailer/__init__.py

The relevant encoding part is

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

TL;DR: Install with pip install ofunctions.mailer

Usage:

from ofunctions.mailer import Mailer

mailer = Mailer(smtp_server='myserver', smtp_port=587)
mailer.send_email(sender_mail='[email protected]', recipient_mails=['[email protected]', '[email protected]'])

Encoding is already set as UTF-8, but you could change encoding to whatever you need by using mailer = Mailer(smtp_srever='...', encoding='latin1')

少年亿悲伤 2024-11-12 18:37:16

我使用标准包做到了这一点: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)

I did it using the standard packages: ssl, smtplib and email.

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文