Python Forum
get email text body: very close but I can't get it [SOLVED}
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
get email text body: very close but I can't get it [SOLVED}
#1
I'm trying to get the text body of emails. To that end I have this code:

def read(username, password, sender_of_interest=None):
    # 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)')
        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(decode=True)
        data_list.append(data_dict)
    print(data_list)
    print(data_dict['body'])

emailData = read('[email protected]', 'myIMAPlogin')
The output seems to be a list of dictionaries, I've tried lots of ways to access the data, but I mostly get something like:

Quote:emailData['body']
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
emailData['body']
TypeError: 'NoneType' object is not subscriptable

The function prints the following, the lower part of which is what I want, starting with the student number, then name, then answers:

Quote:[{'body': <email.message.Message object at 0x7f0c5c4d2be0>}, {'body': '1'}, {'body': <email.message.Message object at 0x7f0c5c4d2e80>}]
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit

1725010103

朱素梅

and

for

to

over

up

around

in

about

beneath

down

I can see what I want before my eyes, but I can't get it!!

Can someone please help me get the text body as a string or list, or just point me in the right direction??
Reply
#2
I just posted in the networking forum about something similar. I am using IMAPClient which I think is just a tad easier than IMAPLib. It might be worth checking out.

https://python-forum.io/Thread-Download-...t-the-data
Reply
#3
Thanks! I will try that.

Do you understand what the code I posted prints? I can see my data in the terminal, but I cannot get it! Grrrr!

I also found this to work on, seems promising for me, but it is from 2014, maybe needs some adjusting.

Also, I'm thinking of taking the raw string of the email and using a regex expression, which would be the student number, as they are all the same 10 digit format. After finding that, I know how long the string should be, hopefully I can cut it out of the raw string. I'll try that too.
Reply
#4
I am trying your suggestion. I have couple of questions if you have the time. I think you do not want to get text "I am trying to figure out how to get the attachment and format the data." I just want the text body, maybe that's the problem.

Q1: What is the number returned from (here 57)?

server.search(['SINCE', '07-Oct-2018'])
[57]
here 57?

This is the result from trying this in my Idle3 shell. You can see there is a problem "Expected list, got <class 'str'>" .

Q2: How do I get the text?

I can print the rawMessage and I see my text, jumbled up with a lot of other stuff.

Quote:>>> import pyzmail
>>> from imapclient import IMAPClient
>>> server = IMAPClient('imap.qq.com', use_uid=True, ssl=True)
>>> server.login('[email protected]', 'myIMAPpassword')
b'Success login ok'
>>> select_info = server.select_folder('Inbox')
>>> server.search(['SINCE', '07-Oct-2018'])
[57]
>>> rawMessage = server.fetch([57], ['BODY[]', 'FLAGS'])
>>> message = pyzmail.PyzMessage.factory(rawMessage[57][b'BODY[]'])
>>> message
<pyzmail.parse.PyzMessage object at 0x7fd765c56978>
>>> print(message.get_payload(1))
Traceback (most recent call last):
File "<pyshell#38>", line 1, in <module>
print(message.get_payload(1))
File "/usr/lib/python3.6/email/message.py", line 257, in get_payload
raise TypeError('Expected list, got %s' % type(self._payload))
TypeError: Expected list, got <class 'str'>
>>> text1 = list(message.get_payload(1))
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
text1 = list(message.get_payload(1))
File "/usr/lib/python3.6/email/message.py", line 257, in get_payload
raise TypeError('Expected list, got %s' % type(self._payload))
TypeError: Expected list, got <class 'str'>
>>> text2 = message.get_payload(1)
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
text2 = message.get_payload(1)
File "/usr/lib/python3.6/email/message.py", line 257, in get_payload
raise TypeError('Expected list, got %s' % type(self._payload))
TypeError: Expected list, got <class 'str'>
>>>
Reply
#5
Well, solved it for my needs in the end.

It seems you cannot put a loop variable in 'server.fetch([loopVariable], ['BODY[]', 'FLAGS'])' I suppose that it is not translated then sent to the imap server, but sent directly.

Now I can print the email body content, I can save it to a text file. The rest does not involve email or internet, I can handle that.

import pyzmail
import pprint
from imapclient import IMAPClient
 
server = IMAPClient('imap.qq.com', use_uid=True, ssl=True)
server.login('[email protected]', 'myIMAPpassword')
select_info = server.select_folder('Inbox')
 
#server.search(['SINCE', '07-Oct-2018'])

unseenMessages = server.search(['UNSEEN'])

#rawMessage = server.fetch([57], ['BODY[]', 'FLAGS'])
rawMessage = server.fetch(unseenMessages, ['BODY[]', 'FLAGS']) 
#print(rawMessage)
#print(message.get_payload(1))
 
#message = pyzmail.PyzMessage.factory(rawMessage[57][b'BODY[]'])
#message.text_part.get_payload().decode(message.text_part.charset)

#print(message.get_payload())

for msgNum in unseenMessages:
	message = pyzmail.PyzMessage.factory(rawMessage[msgNum][b'BODY[]'])
	text = message.text_part.get_payload().decode(message.text_part.charset)
	print('Text' + str(msgNum) + ' = ')
	print(text)
Reply
#6
Thank you for notifying and posting the solution to your issue.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [SOLVED] [BeautifulSoup] How to get this text? Winfried 6 1,927 Aug-17-2022, 03:58 PM
Last Post: Winfried
  Delete empty text files [SOLVED] AlphaInc 5 1,511 Jul-09-2022, 02:15 PM
Last Post: DeaD_EyE
  [SOLVED] [ElementTree] Grab text in attributes? Winfried 3 1,586 May-27-2022, 04:59 PM
Last Post: Winfried
  [SOLVED] Read text file from some point till EOF? Winfried 1 1,911 Oct-10-2021, 10:29 PM
Last Post: Winfried
  Sorting and Merging text-files [SOLVED] AlphaInc 10 4,756 Aug-20-2021, 05:42 PM
Last Post: snippsat
Thumbs Up [SOLVED] Find last occurence of pattern in text file? Winfried 4 4,307 Aug-13-2021, 08:21 PM
Last Post: Winfried
  Replace String in multiple text-files [SOLVED] AlphaInc 5 7,963 Aug-08-2021, 04:59 PM
Last Post: Axel_Erfurt
  A text-based game [SOLVED] Gameri1 6 3,846 Apr-20-2021, 02:26 PM
Last Post: buran
  How to Save Full Email Body to CLOB in Oracle w/Carriage Returns? bmccollum 1 2,234 Mar-12-2020, 10:25 PM
Last Post: Larz60+
  Zeep lib, encrypt soap body miha1234 0 2,814 Sep-12-2019, 07:52 AM
Last Post: miha1234

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020