K
K
Kinishil2020-10-02 14:13:46
Python
Kinishil, 2020-10-02 14:13:46

Error while sending via smtp python?

Code (taken from the Internet):

import smtplib                                              # Импортируем библиотеку по работе с SMTP
import os                                                   # Функции для работы с операционной системой, не зависящие от используемой операционной системы

# Добавляем необходимые подклассы - MIME-типы
import mimetypes                                            # Импорт класса для обработки неизвестных MIME-типов, базирующихся на расширении файла
from email import encoders                                  # Импортируем энкодер
from email.mime.base import MIMEBase                        # Общий тип
from email.mime.text import MIMEText                        # Текст/HTML
from email.mime.image import MIMEImage                      # Изображения
from email.mime.audio import MIMEAudio                      # Аудио
from email.mime.multipart import MIMEMultipart              # Многокомпонентный объект


def send_email(addr_to, msg_subj, msg_text, files):
    addr_from = "[email protected]"                         # Отправитель
    password  = "password"                                  # Пароль

    msg = MIMEMultipart()                                   # Создаем сообщение
    msg['From']    = addr_from                              # Адресат
    msg['To']      = addr_to                                # Получатель
    msg['Subject'] = msg_subj                               # Тема сообщения

    body = msg_text                                         # Текст сообщения
    msg.attach(MIMEText(body, 'plain'))                     # Добавляем в сообщение текст

    process_attachement(msg, files)

    #======== Этот блок настраивается для каждого почтового провайдера отдельно ===============================================
server = smtplib.SMTP_SSL('smtp.yandex.ru', 465)    # Создаем объект SMTP
#server.starttls()                                  # Начинаем шифрованный обмен по TLS
server.login(addr_from, password)                   # Получаем доступ
server.send_message(msg)                            # Отправляем сообщение
server.quit()                                       # Выходим
  #==========================================================================================================================

def process_attachement(msg, files):                        # Функция по обработке списка, добавляемых к сообщению файлов
    for f in files:
        if os.path.isfile(f):                               # Если файл существует
            attach_file(msg,f)                              # Добавляем файл к сообщению
        elif os.path.exists(f):                             # Если путь не файл и существует, значит - папка
            dir = os.listdir(f)                             # Получаем список файлов в папке
            for file in dir:                                # Перебираем все файлы и...
                attach_file(msg,f+"/"+file)                 # ...добавляем каждый файл к сообщению

def attach_file(msg, filepath):                             # Функция по добавлению конкретного файла к сообщению
    filename = os.path.basename(filepath)                   # Получаем только имя файла
    ctype, encoding = mimetypes.guess_type(filepath)        # Определяем тип файла на основе его расширения
    if ctype is None or encoding is not None:               # Если тип файла не определяется
        ctype = 'application/octet-stream'                  # Будем использовать общий тип
    maintype, subtype = ctype.split('/', 1)                 # Получаем тип и подтип
    if maintype == 'text':                                  # Если текстовый файл
        with open(filepath) as fp:                          # Открываем файл для чтения
            file = MIMEText(fp.read(), _subtype=subtype)    # Используем тип MIMEText
            fp.close()                                      # После использования файл обязательно нужно закрыть
    elif maintype == 'image':                               # Если изображение
        with open(filepath, 'rb') as fp:
            file = MIMEImage(fp.read(), _subtype=subtype)
            fp.close()
    elif maintype == 'audio':                               # Если аудио
        with open(filepath, 'rb') as fp:
            file = MIMEAudio(fp.read(), _subtype=subtype)
            fp.close()
    else:                                                   # Неизвестный тип файла
        with open(filepath, 'rb') as fp:
            file = MIMEBase(maintype, subtype)              # Используем общий MIME-тип
            file.set_payload(fp.read())                     # Добавляем содержимое общего типа (полезную нагрузку)
            fp.close()
            encoders.encode_base64(file)                    # Содержимое должно кодироваться как Base64
    file.add_header('Content-Disposition', 'attachment', filename=filename) # Добавляем заголовки
    msg.attach(file)                                        # Присоединяем файл к сообщению



# Использование функции send_email()
addr_to   = "[email protected]"                                # Получатель
files = ["file.txt"]                                      # Список файлов, если вложений нет, то files=[]

send_email(addr_to, "Тема сообщения", "Текст сообщения", files)

Mistake:
Traceback (most recent call last):
  File "send.py", line 78, in <module>
    send_email(addr_to, "От стиллера", "Найдены данные!", files)
  File "send.py", line 26, in send_email
    process_attachement(msg, files)
  File "send.py", line 39, in process_attachement
    attach_file(msg,f)                              # Добавляем файл к сообщению
  File "send.py", line 53, in attach_file
    file = MIMEText(fp.read(), _subtype=subtype)    # Используем тип MIMEText
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python38-32\lib\encodings\cp1251.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 13192: character maps to <undefined>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
muavr, 2020-10-02
@Kinishil

Good afternoon, in your attachment, apparently, the cp1251 encoding is used.
Alternatively, it must be specified when reading the file:

with open(filepath, encoding='cp1251') as fp:       # Открываем файл для чтения
    file = MIMEText(fp.read(), _subtype=subtype)    # Используем тип MIMEText
    fp.close()

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question