Очищення електронної пошти за допомогою Python

@stranger27 · 2025-05-16 15:27 · Team Ukraine

Привіт! Продовжуючи тему корисних для особистого застосування скриптів, сьогодні хочу поділитись з вами кодом, що чистить електронну пошту.

Так що якщо у вас назбиралось декілька тисяч листів за минулі 5 років, серед яких може бути щось важливе, а часу перебирати вручну хронічно не вистачає (чи просто немає бажання), то ця тема саме для вас.

Отже, до вашої уваги наступний скрипт на Python:

import imaplib import email from email.header import decode_header from datetime import datetime, timedelta

Email credentials

EMAIL_USER = "your_email" EMAIL_PASSWORD = "your_app_password" IMAP_SERVER = "your_imap_server" #for google - imap.gmail.com

Adjustable settings

DELETE_UNREAD_OLDER_THAN_DAYS = 30 # Age limit for unread emails DELETE_READ_UNFLAGGED_OLDER_THAN_DAYS = 90 # Age limit for read & unflagged emails DRY_RUN = False # If True, only lists emails without deleting

Custom spam keywords (Always filter spam)

SPAM_KEYWORDS = ["win", "free", "prize", "click here", "lottery", "urgent", "claim now", "exclusive offer", "discount", "get rich"]

Function to reconnect IMAP session

def reconnect_mail(): global mail try: mail.close() mail.logout() except: pass # Avoid crashes if already disconnected mail = imaplib.IMAP4_SSL(IMAP_SERVER, timeout=60) mail.login(EMAIL_USER, EMAIL_PASSWORD) mail.select("inbox")

Connect initially

reconnect_mail() deleted_count = 0 # Counter for deleted emails

def search_and_process(search_query): """Search emails based on query & filter spam if enabled.""" global deleted_count

try:
    status, messages = mail.search(None, search_query)
except imaplib.IMAP4.abort:
    print("Connection lost, reconnecting...")
    reconnect_mail()
    status, messages = mail.search(None, search_query)

if status == "OK":
    message_nums = messages[0].split()
    print(f"Found {len(message_nums)} emails matching criteria: {search_query}")

    if message_nums:
        batch_size = 50  # Process emails in smaller chunks
        for start in range(0, len(message_nums), batch_size):
            batch = message_nums[start:start + batch_size]

            try:
                _, data = mail.fetch(",".join(num.decode() for num in batch), "(RFC822)")
            except imaplib.IMAP4.abort:
                print("Connection lost during fetch, reconnecting...")
                reconnect_mail()
                _, data = mail.fetch(" ".join(num.decode() for num in batch), "(RFC822)")

            for i in range(0, len(data), 2):  # Every email fetch returns two tuples
                if isinstance(data[i], tuple):
                    msg = email.message_from_bytes(data[i][1])

                    # Extract email date
                    email_date = msg["Date"]
                    if email_date:
                        try:
                            email_date = email.utils.parsedate_to_datetime(email_date).strftime("%Y-%m-%d")
                        except:
                            email_date = "Unknown Date"

                    # Decode subject
                    subject, encoding = decode_header(msg["Subject"])[0]
                    if isinstance(subject, bytes):
                        subject = subject.decode(encoding or "utf-8", errors="ignore")

                    # Check if spam
                    is_spam = any(keyword in subject.lower() for keyword in SPAM_KEYWORDS)

                    if is_spam:
                        action_message = "[DRY RUN] Would delete spam: " if DRY_RUN else "Deleting spam: "
                    else:
                        action_message = "[DRY RUN] Would delete: " if DRY_RUN else "Deleting: "


                    print(f"{action_message} ({email_date}) {subject}")
                    if not DRY_RUN:
                        try:
                            mail.store(batch[i//2].decode(), "+FLAGS", "\\Deleted")
                            deleted_count += 1
                        except imaplib.IMAP4.abort:
                            print("Connection lost during deletion, reconnecting...")
                            reconnect_mail()
                            mail.store(batch[i//2].decode(), "+FLAGS", "\\Deleted")

Delete unread emails older than 1 month

search_and_process(f'UNSEEN BEFORE {(datetime.today() - timedelta(days=DELETE_UNREAD_OLDER_THAN_DAYS)).strftime("%d-%b-%Y")}')

Delete read but unflagged emails older than 3 months

search_and_process(f'SEEN BEFORE {(datetime.today() - timedelta(days=DELETE_READ_UNFLAGGED_OLDER_THAN_DAYS)).strftime("%d-%b-%Y")} NOT FLAGGED')

if not DRY_RUN: # Permanently delete flagged emails mail.expunge()

Close the connection

mail.close() mail.logout()

print(f"Total deleted emails: {deleted_count}")

Коментар до коду

Підключення до IMAP-сервера (Gmail):

  • Використовується модуль imaplib, щоб підключитися до пошти через протокол IMAP.

  • Логін виконується за допомогою EMAIL_USER та EMAIL_PASSWORD. Для gmail потрібно ставити пароль застосунку (https://myaccount.google.com/apppasswords)

Налаштування фільтрації пошти:

  • DELETE_UNREAD_OLDER_THAN_DAYS = 30 → Видаляє непрочитані листи, якщо їм більше 30 днів.

  • DELETE_READ_UNFLAGGED_OLDER_THAN_DAYS = 90 → Видаляє прочитані та не позначені прапорцем листи, якщо їм більше 90 днів.

  • DRY_RUN = False → Якщо True, скрипт лише показує, які листи будуть видалені, але не видаляє їх.

Фільтрація спаму:

  • Листи, що містять ключові слова (SPAM_KEYWORDS), видаляються незалежно від віку (наприклад, "win", "free", "prize").

  • Використовується decode_header(), щоб правильно розшифрувати заголовок теми.

Обробка розриву з’єднання:

  • Якщо IMAP-сервер обриває з'єднання (imaplib.IMAP4.abort), скрипт автоматично перепідключається.

  • Використовується reconnect_mail() для повторного з'єднання з сервером.

Пошук та видалення листів:

search_and_process() виконує:

  • Пошук електронних листів, що відповідають критеріям (наприклад, старі, непрочитані, спам).

  • Групове отримання листів у пакетах по 50, щоб уникнути перевантаження серверу.

  • Перевірку на спам, використовуючи ключові слова.

  • Видалення листів, якщо вони відповідають критеріям.

Остаточне очищення пошти:

  • Якщо DRY_RUN = False, викликається mail.expunge(), що остаточно видаляє помічені листи. Для тестування змініть на DRY_RUN = True

  • Закривається з'єднання mail.close() та mail.logout().

Рекомендація: якщо вам сподобався скрипт та у вас є сервер, можна автоматизувати очищення через додання задачі до crontab.

#hive-165469 #ua #ecency #hive #coding #python #neoxian #posh #ecency
Payout: 0.000 HBD
Votes: 59
More interactions (upvote, reblog, reply) coming soon.