The smtplib.server.sendmail function in python raises UnicodeEncodeError: 'ascii' codec can't encode character
smtplib.server
's sendmail method expects a bytes
instance; if it gets a str
it tries to encode it to ASCII, resulting in a UnicodeEncodeError
if the str
contains any non-ASCII characters.
You can workaround this by encoding the message yourself:
>>> msg = 'Hello Wørld'
>>> from_ = 'a@example.com'
>>> to_ = 'b@example.com'
>>> subject = 'Hello'
>>> fmt = 'From: {}\r\nTo: {}\r\nSubject: {}\r\n{}'
>>> server.sendmail(to_, from_, fmt.format(to_, from_, subject, msg).encode('utf-8'))
{}
This will send this message*:
b'From: b@example.com'
b'To: a@example.com'
b'Subject: Hello'
b'Hello W\xc3\xb8rld'
However this workaround will not work if you want to send non-text binary data with your message.
A better solution is to use the EmailMessage class from the email package.
>>> from email.message import EmailMessage
>>> em = EmailMessage()
>>> em.set_content(msg)
>>> em['To'] = to_
>>> em['From'] = from_
>>> em['Subject'] = subject
>>> # NB call the server's *send_message* method
>>> server.send_message(em)
{}
This sends this message; note the extra headers telling the recipient the encoding used:
b'Content-Type: text/plain; charset="utf-8"'
b'Content-Transfer-Encoding: 8bit'
b'MIME-Version: 1.0'
b'To: to@example.com'
b'From: from@example.com'
b'Subject: Hello'
b'X-Peer: ::1'
b''
b'Hello W\xc3\xb8rld'
* Run the command python -m aiosmtpd -n -l localhost:1025
† (Pre-Python3.9: python -m smtpd -n -c DebuggingServer localhost:1025
) in a separate terminal to capture the message data.
† aiosmtpd must be installed using pip
. Unlike smtpd
it is not part of the standard library.
Ascii codec can't encode character when sending email
This error generally occurs due to inconsistency between the string values being dealt with, mainly with mixing variables of type str
with those of type unicode
. Based on the Unicode HOWTO, we must encode it properly to utf-8
. So Produto
becomes Produto.encode("utf-8")
instead.
Issue with smtplib sending mail with unicode characters in Python 3.1
You can instead just use:
msg = MIMEText(message, _charset="UTF-8")
msg['Subject'] = Header(subject, "utf-8")
But either way you still have issues if your frm = "xxxx@xxxxxx.com"
or to = "xxxx@xxxxxx.com"
constains unicode characters. You can't use Header there.
Ascii encoding error during sending a mail
It appears as though whatever character \xa0
represents does not have a representation in ASCII. According to this link, \xa0
is the unicode character for a non-breaking space.
Since this is really just a space, you could try and replace all \xa0
characters in your string:
messages = ["\n".join(msg.replace(u'\xa0', u' ')) for msg in messages]
To be fair, space and non-breaking spaces function differently, so depending on where this character appears in your message, the output could look slightly different after replacing the non-breaking spaces with regular spaces.
Another option is to ignore any characters that produce any error. This solution is not ideal because you could lose characters that end-up changing the formatting (or sometimes meaning) of your text. Replacing the non-breaking space with a normal space is smart to do regardless, but for all other pesky characters:
msg.encode("ascii", errors="ignore")
Alternatively, you can do msg.encode("ascii", errors="replace")
but that will replace these characters with a '?' which doesn't look so nice.
UnicodeEncodeError: 'ascii' codec can't encode character in position 0-4: ordinal not range(128)
server.sendmail('email.com', 'email.com', 'привет'.encode('utf-8'))
Python: UnicodeEncodeError: 'ascii' codec can't encode character '\u039f' in position 0: ordinal not in range(128)
I assume that the error is on the server.sendmail(email, remail, message)
line.
The documentation for sendmail
is explicit (emphazise mine):
... msg may be a string containing characters in the ASCII range, or a byte string. A string is encoded to bytes using the ascii codec, and lone \r and \n characters are converted to \r\n characters. A byte string is not modified.
As you pass a message containing Greek (non ascii) characters, its encoding with the ASCII codec raises the error.
How to fix:
The simplest way is IMHO to use the send_message
method:
from email.message import EmailMessage
...
msg = EmailMessage()
msg.set_content(message)
with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
server.login(email, password)
server.send_message(msg, email, remail) #remail is the receiver email
It will automatically encode the message in utf8 and add the relevant headers.
Related Topics
How to Reverse Lists in Python, Getting "Nonetype" as List
Generating Random Dates Within a Given Range in Pandas
Syntaxerror Inconsistency in Python
Why Do "Not a Number" Values Equal True When Cast as Boolean in Python/Numpy
How to Randomly Choose a Maths Operator and Ask Recurring Maths Questions with It
Typeerror: Unsupported Operand Type(S) for /: 'Str' and 'Str'
Sqlalchemy: What's the Difference Between Flush() and Commit()
Python Regex Escape Operator \ in Substitutions & Raw Strings
Why Sum on Lists Is (Sometimes) Faster Than Itertools.Chain
Pandas: Cast Column to String Does Not Work
Python String.Strip Stripping Too Many Characters
How to Move Pandas Data from Index to Column After Multiple Groupby
Scrape Website with Dynamic Mouseover Event
Verifying Compatibility in Compiling Extension Types, and Using Them with Cdef