Как установить несколько условий (И и ИЛИ) в imaplib.IMAP4_SSL.search()

#python-3.x #email #imap #imaplib

#python-3.x #Адрес электронной почты #imap #imaplib

Вопрос:

Мне нужно фильтровать электронные письма и помечать их на основе некоторых условий.

Это мой код:

 def get_inbox():

    os.chdir("C:/Users/simeone/Desktop/FilterEmails")
    df = {}
    df = pd.read_excel("Filtri.xlsx", encoding='utf-8', sheet_name = ['FROM', 'TEXT', 'SUBJECT'])
    filters = []
    for key in df.keys():
        fil = [ '(OR '   key   ' '   '"'   name   '"'  ' UNSEEN)' for name in list(df[key][df[key].columns[0]])]
        str1 = ' '.join(fil)
        filters.append(str1)
    filtro = ' '.join(filters)
    

    mail = imaplib.IMAP4_SSL(host)
    mail.login(username, password)
    mail.select("inbox")


    _, search_data = mail.search(None, filtro)  
  

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

Я импортирую условия из Excel, где они разделены на from, text, subject, а затем накладываю на них условия.

Проблема в том, что код выбирает каждое невидимое электронное письмо, независимо от того, из теста и темы.

Я четко представляю логику, но не могу правильно перевести в код. Что должен делать mail.search, так это: И НЕВИДИМЫЙ И (ИЛИ ИЗ «####» ИЛИ ТЕМЫ «####»), что означает, что возьмите все невидимые и поставьте ярлык на те, у которых есть ИЛИ «эта тема», ИЛИ они от «этого человека».

По-другому, пометьте все те, которые из xxx ИЛИ с темой xxx, но которые также (И) НЕВИДИМЫ.

Комментарии:

1. И является оператором по умолчанию, его нельзя указать. ИЛИ — это префиксный оператор, который принимает два параметра. Имейте в виду, что не все серверы хорошо реализуют язык поиска, но вы, вероятно, хотите что-то похожее UNSEEN OR (FROM ...) (SUBJECT ...) на один термин. Если вы начнете смешивать более двух или трех из них вместе, вы, вероятно, переполните стек поиска удаленного сервера.

2. опция, которую вы мне дали, к сожалению, не работает .. также просто для того, чтобы указать, что данные ИЗ и SUBJECT также НЕВИДИМЫ, поэтому, если я помещу ИЛИ в эту позицию, это просто даст мне все невидимые, а не невидимые, у которых есть данные ИЗ и SUBJECT

3. ИЛИ не является инфиксным оператором. Это префиксный оператор. Это не означает, как это выглядит на английском языке, это означает: (UNSEEN) и (OR (FROM ...) (SUBJECT ...)) . ИЛИ влияет на две вещи, которые следуют за ним, а не до и после.

4. На английском языке ИЛИ идет между вещами: x or y . x и y — до и после . На языке поиска IMAP OR предшествует вещам: OR X Y. x и y оба идут после .

5. ИЛИ принимает только два операнда.. Если вы хотите больше, вам нужно связать их: OR (X) (OR (Y) (Z)) , или, возможно: OR (OR (X) (Y)) (Z) например. Технически круглые скобки не должны быть нужны, но это может помочь.

Ответ №1:

На языке поиска IMAP AND это операция по умолчанию и операция с OR двумя префиксами операндов.

Для AND вас просто соедините их вместе: «a и b» есть A B .

OR Это означает, что если вы хотите «a или b», вам нужно написать «ИЛИ (A) (B)». Технически круглые скобки на самом деле не нужны, но могут помочь, если ваши условия становятся сложными.

Если вам нужно больше двух вещей, вам нужно объединить OR вместе. Каждый из них может принимать только два параметра. Вы могли бы написать «x или y или z» как либо OR (OR X Y) Z или OR X (OR Y Z) . Опять же, скобки необязательны, но могут помочь некоторым серверам лучше их анализировать.

Склеивание всего этого вместе «a и (x или y или z)» — это A OR OR X Y Z .

Существует много серверного программного обеспечения, которое не очень хорошо обрабатывает сложные запросы. Если ваш запрос становится слишком сложным или реализация серверов незначительна, вы можете рассмотреть возможность самостоятельного кэширования метаданных (с помощью UID FETCH BODY[HEADER] ) и выполнения поиска локально. Эти данные теоретически неизменяемы, поэтому вам нужно будет получить их только один раз.