Reputation: 137
There's an email blasted out every morning containing an Excel attachment. I would like to be able to grab each of these attachments and save them into the same folder. I attempted the following code:
Downloading multiple attachments using imaplib
https://gist.github.com/jasonrdsouza/1674794
https://gist.github.com/baali/2633554
But I keep running into the same error:
initial_value must be str or None, not bytes
I assume this is because there's something wrong with one of the emails/attachments, but I'm not sure how to troubleshoot.
Code:
detach_dir = 'C:/Users/myname'
m = imaplib.IMAP4_SSL("outlook.office365.com")
m.login('[email protected]','password')
m.select("INBOX")
resp, items = m.search(None, '(SUBJECT "Daily Report")')
items = items[0].split()
for emailid in items:
resp, data = m.fetch(emailid, "(RFC822)")
email_body = data[0][1]
mail = email.message_from_string(email_body)
#^This is where the error occurs
temp = m.store(emailid,'+FLAGS', '\\Seen')
m.expunge()
if mail.get_content_maintype() != 'multipart':
continue
#print "["+mail["From"]+"] :" + mail["Subject"]
for part in mail.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
att_path = os.path.join(detach_dir, filename)
if not os.path.isfile(att_path) :
fp = open(att_path, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
This is the error:
TypeError Traceback (most recent call last)
<ipython-input-6-07c04531d5aa> in <module>()
5 resp, data = m.fetch(emailid, "(RFC822)")
6 email_body = data[0][1]
----> 7 mail = email.message_from_string(email_body)
8 #This is where the error occurs
9 temp = m.store(emailid,'+FLAGS', '\\Seen')
~\AppData\Local\Continuum\anaconda3\lib\email\__init__.py in message_from_string(s, *args, **kws)
36 """
37 from email.parser import Parser
---> 38 return Parser(*args, **kws).parsestr(s)
39
40 def message_from_bytes(s, *args, **kws):
~\AppData\Local\Continuum\anaconda3\lib\email\parser.py in parsestr(self, text, headersonly)
66 the file.
67 """
---> 68 return self.parse(StringIO(text), headersonly=headersonly)
69
70
TypeError: initial_value must be str or None, not bytes
The code works fine when I tested it for a different subject, so I assume there's one email or attachment that's screwing it up. Reducing the search to emails sent on Jan 1 onwards might do the trick, but I don't know how to manipulate the search for two parameters:
typ, msgs = mails.search(None, '(SUBJECT "Daily Report")', 'SENTSINCE 01-JAN-2018')
Upvotes: 0
Views: 2374