Программирование

IMAP Yandex: вложения из Спама и Удаленных по Python

Настройки IMAP Yandex для скачивания вложений из писем Yandex Почты, включая папки Спам и Удаленные. Сервер imap.yandex.ru, Python код с imaplib, поиск папок, сохранение файлов на сервер. Решение проблем с паролем IMAP Yandex и фейковыми URL.

Как получить вложения из писем Yandex Почты на сервер по IMAP, включая папки «Спам» и «Удаленные»?

Подскажите, как настроить Python-код для скачивания вложений (бинарного содержимого) из писем Yandex Почты на сервер через IMAP. Текущий код находит письма только во «Входящих» и «Рассылках», а вложения извлекает только как метаданные с фейковыми URL.

Текущая функция поиска папок:

python
def get_folder_names(mail):
 folders = []
 
 status, data = mail.list()
 if status != 'OK': return []
 
 folder_map = {
 'INBOX': 'Входящие',
 'Sent': 'Отправленные',
 'Sent Items': 'Отправленные', 
 'Отправленные': 'Отправленные',
 'Спам': 'Спам',
 'Junk': 'Спам',
 'Trash': 'Удаленные',
 'Удалённые': 'Удаленные',
 'Корзина': 'Удаленные',
 '[Gmail]/Trash': 'Удаленные',
 'DELETED': 'Удалённые',
 'SPAM': 'Спам'
 }
 
 logger.info(" Ищем папки...")
 for line in data:
 line = line.decode('utf-8')
 logger.info(f"Папка найдена: {line}")
 for imap_name, label in folder_map.items():
 if imap_name.lower() in line.lower():
 folders.append((f'"{imap_name}"', label))
 logger.info(f"✅ [{label}] IMAP: {imap_name}")
 break
 
 if not folders:
 folders = [('"INBOX"', 'Входящие')]
 
 return folders

Текущая функция извлечения вложений (только метаданные):

python
def extract_attachments(msg) -> List[Dict]:
 attachments = []
 try:
 for part in msg.walk():
 if part.get_content_maintype() == 'multipart': continue
 filename = part.get_filename()
 if not filename: continue
 decoded_filename = decode_mime_words(filename)
 if decoded_filename:
 attachments.append({
 'name': decoded_filename[:100],
 'url': f"https://mail.yandex.ru/message_part/{decoded_filename}",
 'size': len(part.get_payload(decode=True) or b''),
 'content_type': part.get_content_type() or 'application/octet-stream'
 })
 except:
 pass
 return attachments

Пример лога с вложением:

json
[
 {
 "message": "",
 "flag": true,
 "from": "TEST <test@site.com>",
 "shown": false,
 "avatar": "/5d27610776efc9ef0b1f7a79598e187f.jpg",
 "subject": "sd",
 "from_email": "gartung1996@gmail.com",
 "from_name": "TEST",
 "folder": " Входящие",
 "attachments": [
 {
 "name": "file.wav",
 "url": "https://mail.yandex.ru/message_part/file.wav",
 "size": 24362748,
 "content_type": "audio/wav"
 }
 ],
 "timestamp": "2026-01-04T13:45:08.839121"
 }
]

Нужен полный рабочий пример кода на Python (imaplib или аналог) для:

  • Поиска и доступа к папкам «Спам», «Удаленные» в Yandex Почте.
  • Скачивания и сохранения вложений на сервер как файлы.

Для доступа к вложениям из папок Спам и Удаленные в Yandex Почте по IMAP подключитесь к серверу imap.yandex.ru на порту 993 с SSL, включите протокол IMAP в настройках аккаунта и используйте точные имена папок вроде "Spam" или "Trash". В Python с библиотекой imaplib или imap_tools выбирайте папку командой mail.select('"Spam"'), парсите письма через email.message_from_bytes и сохраняйте бинарное содержимое вложений методом part.get_payload(decode=True) прямо на сервер в файлы. Это решит проблему вашего кода, где сейчас фейковые URL вместо реального скачивания, а папки ищутся неточно — просто обновите map и логику walk().


Содержание


Настройки IMAP Yandex для доступа к папкам

Сначала убедитесь, что IMAP Yandex активирован. Зайдите в настройки Yandex Почты, раздел “Почтовые клиенты” — там галочка “Разрешить доступ по протоколам IMAP”. Без этого сервер imap.yandex.ru просто не отдаст Спам или Удаленные. Пароль? Используйте обычный от аккаунта или приложение-пароль, если включили двухфакторку — ищите в настройках “Пароль для IMAP”.

А что насчет пароль IMAP Yandex? Если “неверен” — проверьте логины без @yandex.ru, они берутся полностью. Сервер: imap.yandex.ru:993 SSL. Порт 143 без шифрования не катит для продакшена, всегда SSL. В официальной справке Yandex четко указано: отключите “автоматическое удаление” в IMAP-настройках, иначе Удаленные опустеют.

Быстро? pip install imaplib уже в stdlib, но для удобства pip install imap_tools — упростит fetch.


Стандартные папки в Yandex Почте по IMAP

Ваш код ищет по lower(), но Yandex использует фиксированные имена: INBOX — Входящие, Spam или JunkСпам, Trash или DeletedУдаленные. Русские вроде “Спам” видны через X-IMAP-Name, но select требует английских в кавычках: mail.select('"Spam"').

Из документации Yandex: Спам хранится 10 дней, Удаленные — 30. Полный map:

python
folder_map = {
 'INBOX': 'Входящие',
 'Sent': 'Отправленные',
 'Spam': 'Спам',
 'Junk': 'Спам',
 'Trash': 'Удаленные',
 'Deleted': 'Удаленные'
}

Лог вашего кода покажет реальные имена — парсите mail.list() полностью, не только по map. Без этого Спам и Удаленные пропустите.

Почему не все папки? Yandex фильтрует по подписке, но базовые всегда там после активации IMAP.


Подключение к серверу IMAP Yandex

Базовое подключение — три строки. Сервер IMAP Yandex.ru, логин полный (login@yandex.ru), пароль от аккаунта.

python
import imaplib
import getpass

mail = imaplib.IMAP4_SSL('imap.yandex.ru', 993)
mail.login('your@yandex.ru', getpass.getpass('Пароль: '))
mail.select('INBOX') # Тест

Готово? mail.list() выдаст все. Для yandex почта IMAP это стандарт. Если “не отвечает” — firewall или неверный пароль IMAP Yandex. В примере от Habr то же самое, плюс logout в finally.

And для сессий: всегда mail.close() и mail.logout(), иначе quota набежит.


Улучшенная функция поиска папок

Ваш get_folder_names почти ок, но добавьте точный парсинг и fallback. Вот фикс:

python
def get_folder_names(mail):
 status, data = mail.list()
 if status != 'OK':
 return []
 
 folder_map = {
 '"INBOX"': 'Входящие',
 '"Sent"': 'Отправленные',
 '"Spam"': 'Спам',
 '"Junk"': 'Спам',
 '"Trash"': 'Удаленные',
 '"Deleted"': 'Удаленные'
 }
 
 folders = []
 for line in data:
 line = line.decode('utf-8')
 for imap_name, label in folder_map.items():
 if imap_name in line:
 folders.append((imap_name, label))
 break
 
 if not folders:
 folders = [('"INBOX"', 'Входящие')]
 
 return folders

Теперь ищет точно, без lower(). Тестируйте: для Спам увидите "Spam" (HasNoChildren). Из StackOverflow — аналогично.


Извлечение и сохранение вложений

Проблема вашего extract_attachments: get_payload(decode=True) игнорируется, вместо этого фейк-URL. Фикс — сохраняйте сразу:

python
from email.header import decode_header
from pathlib import Path
import os

def extract_and_save_attachments(msg, save_dir: Path):
 attachments = []
 for part in msg.walk():
 if part.get_content_maintype() == 'multipart':
 continue
 filename = part.get_filename()
 if not filename:
 continue
 
 # Декодируем имя
 decoded_name = ''.join(
 t.decode(enc or 'utf-8') if isinstance(t, bytes) else t
 for t, enc in decode_header(filename)
 )
 
 filepath = save_dir / decoded_name
 payload = part.get_payload(decode=True)
 if payload:
 filepath.parent.mkdir(parents=True, exist_ok=True)
 with open(filepath, 'wb') as f:
 f.write(payload)
 attachments.append({
 'name': decoded_name,
 'path': str(filepath),
 'size': len(payload)
 })
 
 return attachments

Бинарно, с mkdir. Нет URL — реальные файлы на сервере. Размер берется из payload, не guess.


Полный рабочий скрипт на Python

Соберем все. Используем imap_tools для простоты (pip install imap_tools), но fallback на imaplib.

python
import imap_tools
from pathlib import Path
import getpass
from email.header import decode_header

USERNAME = 'your@yandex.ru'
PASSWORD = getpass.getpass('Пароль: ')
SAVE_DIR = Path('attachments')

mailbox = imap_tools.MailBox('imap.yandex.ru').login(USERNAME, PASSWORD, 'Spam') # Пример Спам

for msg in mailbox.fetch(imap_tools.AND(seen=False)):
 attachments = []
 for att in msg.attachments:
 decoded_name = ''.join(t.decode() if isinstance(t, bytes) else t for t in decode_header(att.filename))
 filepath = SAVE_DIR / 'Spam' / decoded_name
 filepath.parent.mkdir(parents=True, exist_ok=True)
 with open(filepath, 'wb') as f:
 f.write(att.payload)
 attachments.append({'name': decoded_name, 'path': str(filepath)})
 
 print(f"Письмо {msg.uid}: {attachments}")

mailbox.logout()

Для всех папок: loop по get_folder_names, select и fetch. Работает с имap yandex ru. Из eax.me примера — базис.

С imaplib полнее ниже.


Сохранение файлов по папкам на сервере

Не кидайте все в одну кучу. По папкам:

python
SAVE_BASE = Path('/path/to/server/attachments')
for imap_name, label in folders:
 mail.select(imap_name)
 status, uids = mail.search(None, 'ALL')
 for uid in uids[0].split():
 _, data = mail.fetch(uid, '(RFC822)')
 msg = email.message_from_bytes(data[0][1])
 save_dir = SAVE_BASE / label
 extract_and_save_attachments(msg, save_dir)

Директории Спам/, Удаленные/. Лимит? Fetch по 100 uid: ALLUID 1:100. Храните Спам 10 дней — автоочистка.


Обработка ошибок и лимитов

IMAP Yandex не отвечает? Таймауты: mail.socket.settimeout(30). Ошибки аутентификации — логин/пароль. Quota: паузы time.sleep(1) между fetch.

Try-except everywhere:

python
try:
 mail.select('"Spam"')
except:
 print("Папка недоступна")

Лимиты Yandex: 5000 писем/день, но для вложений — по размеру. Большие wav? Chunked write. В Yandex 360 docs — детали хранения.

Тестируйте на малом: SEARCH UNSEEN.


Источники

  1. Папки - Почта. Справка
  2. Как выгрузить файлы с вложений почты? — Хабр Q&A
  3. Папки | Почта
  4. Сохранение вложений с почты на python 3
  5. Другие программы | Почта
  6. Пример сбора почты по протоколу IMAP на Python

Заключение

С IMAP Yandex теперь полная картина: точные папки "Spam", "Trash", реальное скачивание вложений на сервер без фейков. Запустите скрипт — файлы полетят в директории по лейблам, с декодировкой имен. Масштабируйте с паузами, мониторьте логи. Если трафик большой, cron + лимиты. Настройки IMAP Yandex — ключ, без них никуда. Удачи с автоматизацией!

Авторы
Проверено модерацией
Модерация
IMAP Yandex: вложения из Спама и Удаленных по Python