¿Cómo realizo una búsqueda IMAP en Python (usando Gmail e imaplib)?
Pregunta
En Gmail, tengo un montón de mensajes etiquetados.
Me gustaría usar un cliente IMAP para recibir esos mensajes, pero no estoy seguro de qué es el conjuro de búsqueda.
c = imaplib.IMAP4_SSL('imap.gmail.com')
c.list()
('OK', [..., '(\\HasNoChildren) "/" "GM"', ...])
c.search(???)
No estoy encontrando muchos ejemplos para este tipo de cosas.
Solución
imaplib
es intencionalmente una envoltura delgada alrededor del protocolo IMAP, supongo que para permitir un mayor grado de flexibilidad del usuario y una mayor capacidad para adaptarse a los cambios en la especificación IMAP. Como resultado, realmente no ofrece ninguna estructura para sus consultas de búsqueda y requiere que esté familiarizado con el Especificación IMAP .
Como verás en la sección " 6.4.4. Comando de búsqueda " ;, hay muchas cosas que puede especificar para el criterio de búsqueda. Tenga en cuenta que debe SELECCIONAR
un buzón (el nombre de IMAP para una carpeta) antes de poder buscar cualquier cosa. (La búsqueda en varias carpetas requiere simultáneamente múltiples conexiones IMAP, según tengo entendido). IMAP4.list
lo ayudará a descubrir cuáles son los identificadores del buzón.
También es útil para formular las cadenas que pasas a imaplib
" 9. Sintaxis formal " desde el RFC vinculado a arriba.
El r '(\ HasNoChildren) " / "'
es un indicador de buzón en el buzón raíz, /
. Ver " 7.2.6. Respuesta de BANDERAS " ;.
¡Buena suerte!
Otros consejos
import imaplib
obj = imaplib.IMAP4_SSL('imap.gmail.com', 993)
obj.login('username', 'password')
obj.select('**label name**') # <-- the label in which u want to search message
obj.search(None, 'FROM', '"LDJ"')
Se accede a las etiquetas exactamente como las carpetas IMAP , según Google.
La forma más fácil de usar imaplib con Gmail es usar el atributo X-GM-RAW
como se describe en página de Extensiones de Imap de Gmail .
El proceso sería así:
Primero conéctese a la cuenta con el correo electrónico y la contraseña apropiados:
c = imaplib.IMAP4_SSL('imap.gmail.com', 993)
email = 'eggs@spam'
password = 'spamspamspam'
c.login(email, password)
Luego conéctese a una de las carpetas / etiquetas:
c.select("INBOX")
Si es necesario, puede enumerar todas las carpetas / etiquetas disponibles con c.list ()
.
Finalmente, usa el método de búsqueda:
gmail_search = "has:attachment eggs OR spam"
status, data = c.search(None, 'X-GM-RAW', gmail_search)
En gmail_search
puede usar la misma sintaxis de búsqueda que se usa en búsqueda avanzada de gmail .
El comando de búsqueda devolverá el estado del comando y los identificadores de todos los mensajes que coincidan con tu búsqueda de gmail.
Después de esto, puedes obtener cada mensaje por ID con:
for id in data[0].split():
status, data = gmail.fetch(id, '(BODY[TEXT])')
Me ha sorprendido bastante que imaplib no haga gran parte del análisis de respuesta. Y parece que las respuestas fueron diseñadas para ser difíciles de analizar.
FWIW, para responder a mi propia pregunta: c.search (Ninguno, 'GM')
(No tengo idea de qué trata la parte '(\ HasNoChildren) " / "')