IMAP Yandex: вложения из Спама и Удаленных по Python
Настройки IMAP Yandex для скачивания вложений из писем Yandex Почты, включая папки Спам и Удаленные. Сервер imap.yandex.ru, Python код с imaplib, поиск папок, сохранение файлов на сервер. Решение проблем с паролем IMAP Yandex и фейковыми URL.
Как получить вложения из писем Yandex Почты на сервер по IMAP, включая папки «Спам» и «Удаленные»?
Подскажите, как настроить Python-код для скачивания вложений (бинарного содержимого) из писем Yandex Почты на сервер через IMAP. Текущий код находит письма только во «Входящих» и «Рассылках», а вложения извлекает только как метаданные с фейковыми URL.
Текущая функция поиска папок:
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
Текущая функция извлечения вложений (только метаданные):
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
Пример лога с вложением:
[
{
"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 для доступа к папкам
- Стандартные папки в Yandex Почте по IMAP
- Подключение к серверу IMAP Yandex
- Улучшенная функция поиска папок
- Извлечение и сохранение вложений
- Полный рабочий скрипт на Python
- Сохранение файлов по папкам на сервере
- Обработка ошибок и лимитов
- Источники
- Заключение
Настройки 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:
folder_map = {
'INBOX': 'Входящие',
'Sent': 'Отправленные',
'Spam': 'Спам',
'Junk': 'Спам',
'Trash': 'Удаленные',
'Deleted': 'Удаленные'
}
Лог вашего кода покажет реальные имена — парсите mail.list() полностью, не только по map. Без этого Спам и Удаленные пропустите.
Почему не все папки? Yandex фильтрует по подписке, но базовые всегда там после активации IMAP.
Подключение к серверу IMAP Yandex
Базовое подключение — три строки. Сервер IMAP Yandex.ru, логин полный (login@yandex.ru), пароль от аккаунта.
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. Вот фикс:
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. Фикс — сохраняйте сразу:
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.
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 полнее ниже.
Сохранение файлов по папкам на сервере
Не кидайте все в одну кучу. По папкам:
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: ALL → UID 1:100. Храните Спам 10 дней — автоочистка.
Обработка ошибок и лимитов
IMAP Yandex не отвечает? Таймауты: mail.socket.settimeout(30). Ошибки аутентификации — логин/пароль. Quota: паузы time.sleep(1) между fetch.
Try-except everywhere:
try:
mail.select('"Spam"')
except:
print("Папка недоступна")
Лимиты Yandex: 5000 писем/день, но для вложений — по размеру. Большие wav? Chunked write. В Yandex 360 docs — детали хранения.
Тестируйте на малом: SEARCH UNSEEN.
Источники
- Папки - Почта. Справка
- Как выгрузить файлы с вложений почты? — Хабр Q&A
- Папки | Почта
- Сохранение вложений с почты на python 3
- Другие программы | Почта
- Пример сбора почты по протоколу IMAP на Python
Заключение
С IMAP Yandex теперь полная картина: точные папки "Spam", "Trash", реальное скачивание вложений на сервер без фейков. Запустите скрипт — файлы полетят в директории по лейблам, с декодировкой имен. Масштабируйте с паузами, мониторьте логи. Если трафик большой, cron + лимиты. Настройки IMAP Yandex — ключ, без них никуда. Удачи с автоматизацией!