Eu tenho esse código, mas na verdade não recebo o texto do e-mail.
Tenho que decodificar o texto do e-mail?
import sys
import imaplib
import getpass
import email
import email.header
from email.header import decode_header
import base64
def read(username, password, sender_of_interest):
# Login to INBOX
imap = imaplib.IMAP4_SSL("imap.mail.com", 993)
imap.login(username, password)
imap.select('INBOX')
# Use search(), not status()
# Print all unread messages from a certain sender of interest
if sender_of_interest:
status, response = imap.uid('search', None, 'UNSEEN', 'FROM {0}'.format(sender_of_interest))
else:
status, response = imap.uid('search', None, 'UNSEEN')
if status == 'OK':
unread_msg_nums = response[0].split()
else:
unread_msg_nums = []
data_list = []
for e_id in unread_msg_nums:
data_dict = {}
e_id = e_id.decode('utf-8')
_, response = imap.uid('fetch', e_id, '(RFC822)')
html = response[0][1].decode('utf-8')
email_message = email.message_from_string(html)
data_dict['mail_to'] = email_message['To']
data_dict['mail_subject'] = email_message['Subject']
data_dict['mail_from'] = email.utils.parseaddr(email_message['From'])
#data_dict['body'] = email_message.get_payload()[0].get_payload()
data_dict['body'] = email_message.get_payload()
data_list.append(data_dict)
print(data_list)
# Mark them as seen
#for e_id in unread_msg_nums:
#imap.store(e_id, '+FLAGS', '\Seen')
imap.logout()
return data_dict
Então eu faço isso:
print('Getting the email text bodiies ... ')
emailData = read(usermail, pw, sender_of_interest)
print('Got the data!')
for key in emailData.keys():
print(key, emailData[key])
A saída é:
mail_to [email protegido]
mail_subject Obter arquivo json
mail_from ('Pedro Rodriguez', ' [email protegido] ')
corpo [<email.message.Message object em 0x7f7d9f928df0>, <email.message.Message object em 0x7f7d9f928f70>]
Como realmente obter o texto do e-mail?
Tentei a sugestão, mas parece que falha porque é multiparte, com um arquivo de texto anexado:
def read(username, password, sender_of_interest):
# Login to INBOX
imap = imaplib.IMAP4_SSL("imap.qq.com", 993)
imap.login(username, password)
imap.select('INBOX')
# Use search(), not status()
# Print all unread messages from a certain sender of interest
if sender_of_interest:
status, response = imap.uid('search', None, 'UNSEEN', 'FROM {0}'.format(sender_of_interest))
else:
status, response = imap.uid('search', None, 'UNSEEN')
if status == 'OK':
unread_msg_nums = response[0].split()
else:
unread_msg_nums = []
data_list = []
for e_id in unread_msg_nums:
data_dict = {}
e_id = e_id.decode('utf-8')
_, response = imap.uid('fetch', e_id, '(RFC822)')
email_message = email.message_from_bytes(response[0][1], policy=default)
#html = response[0][1].decode('utf-8')
#email_message = email.message_from_string(html)
data_dict['mail_to'] = email_message['To']
data_dict['mail_subject'] = email_message['Subject']
data_dict['mail_from'] = email.utils.parseaddr(email_message['From'])
#data_dict['body'] = email_message.get_payload()[0].get_payload()
#data_dict['body'] = email_message.get_payload()[0]
data_dict['body'] = email_message.get_body('html', 'text').get_payload(decode=True)
data_list.append(data_dict)
print(data_list)
# Mark them as seen
#for e_id in unread_msg_nums:
#imap.store(e_id, '+FLAGS', '\Seen')
imap.logout()
return data_dict
Obtenha este erro:
emailData = read(usermail, pw, sender_of_interest) Traceback (última chamada mais recente): Arquivo "/usr/lib/python3.10/idlelib/run.py", linha 578, em runcode exec(code, self.locals) Arquivo "<pyshell#126>", linha 1, no arquivo "<pyshell#125>", linha 29, em leitura TypeError: MIMEPart.get_body() leva de 1 a 2 argumentos posicionais, mas 3 foram fornecidos
Importei o BeautifulSoup também para obter o texto do html:
from bs4 import BeautifulSoup
# this seems to work
def read(username, password, sender_of_interest):
# Login to INBOX
imap = imaplib.IMAP4_SSL("imap.qq.com", 993)
imap.login(username, password)
imap.select('INBOX')
# Use search(), not status()
# Print all unread messages from a certain sender of interest
if sender_of_interest:
status, response = imap.uid('search', None, 'UNSEEN', 'FROM {0}'.format(sender_of_interest))
else:
status, response = imap.uid('search', None, 'UNSEEN')
if status == 'OK':
unread_msg_nums = response[0].split()
else:
unread_msg_nums = []
data_list = []
for e_id in unread_msg_nums:
data_dict = {}
e_id = e_id.decode('utf-8')
_, response = imap.uid('fetch', e_id, '(RFC822)')
email_message = email.message_from_bytes(response[0][1], policy=default)
html = response[0][1].decode('utf-8')
data_dict['mail_to'] = email_message['To']
data_dict['mail_subject'] = email_message['Subject']
data_dict['mail_from'] = email.utils.parseaddr(email_message['From'])
body = email_message.get_body(('html', 'text')).get_payload(decode=True)
soup = BeautifulSoup(body, 'html.parser')
div_bs4 = soup.find('div')
text = div_bs4.string
data_dict['body'] = text
data_list.append(data_dict)
print(data_list)
# Mark them as seen
#for e_id in unread_msg_nums:
#imap.store(e_id, '+FLAGS', '\Seen')
imap.logout()
return data_dict
A saída para body é agora:
'body': 'Você consegue o anexo?'
Agora só falta pegar o anexo!
Dependendo do que exatamente você quer dizer com "o texto", você provavelmente desejará o
get_body
método. Mas você está destruindo completamente o e-mail antes de chegar a esse ponto. O que você recebe do servidor não é "HTML" e convertê-lo em uma string para chamá-message_from_string
lo é indireto e sujeito a erros. O que você obtém são bytes; use omessage_from_bytes
método diretamente. (Isso evita todos os tipos de problemas quando os bytes não são UTF-8; omessage_from_string
método só fazia sentido no Python 2, que não tinha explícitobytes
.)O uso de a
policy
seleciona o (não muito) novoEmailMessage
; você precisa do Python 3.3+ para que isso esteja disponível. A classe herdada mais antigaemail.Message
não tinha esse método, mas também deveria ser evitado no novo código por muitos outros motivos.Isso poderia falhar para mensagens multipartes com estruturas aninhadas não triviais; o
get_body
método sem argumentos pode retornar umamultipart/alternative
parte da mensagem e então você deve partir daí. Você não especificou a aparência esperada de suas mensagens, então não vou me aprofundar mais nisso.Mais fundamentalmente, você provavelmente precisará de uma imagem mais detalhada de como as mensagens de e-mail modernas são estruturadas. Consulte Quais são as "partes" em um e-mail multipartes?