Read attachments data from email using python - python

I'm attempting to use code to read an email and its attachments. I can read the email using Python's extract msg module, but not the attachment content. I am printing the attachments variable but its showing list object and not the content. The code for this is provided below. Please share your thoughts on this.
import extract_msg
import glob
import re
f = glob.glob('Time Off -DAYS.msg')
for filename in f:
msg = extract_msg.Message(filename)
msg_from = msg.sender
msg_date = msg.date
msg_subj = msg.subject
msg_message = msg.body
attachments = msg.attachments
msg_to = msg.to
print("To:-",msg_to)
print("From:-",msg_from)
print ("Date:-",msg.date)
print(attachments)
attachments data: Email has 2 attachments
[<extract_msg.attachment.Attachment object at 0x0000024444C9FEF0>, <extract_msg.attachment.Attachment object at 0x0000024444E39C50>]

you use multiple libraries to reading Email Data
smtplib , imaplib, pywin32
I use pywin32 here and use Outlook
to reading and downloading Emails and Attachments:
first, you have to install and import the module:
pip install pywin32
import win32com.client
second Establish a Connection:
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
third Read the Email:
# Access to the email in the inbox
messages = inbox.Items
# get the first email
message = messages.GetFirst()
# get the last email
#message = messages.GetLast()
# to loop thru the email in the inbox
while True:
try:
print(message.subject) # get the subject of the email
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
except:
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
The above example shows how to print the subject of all of the emails in the Inbox.
Below are some of the common properties:
message.subject
message.senton # return the date & time email sent
message.senton.date()
message.senton.time()
message.sender
message.SenderEmailAddress
message.Attachments # return all attachments in the email
Download and Email Attachment:
attachments = message.Attachments
# return the first item in attachments
attachment = attachments.Item(1)
# the name of attachment file
attachment_name = str(attachment).lower()
attachment.SaveASFile(path+ '\\' + attachment_name)
I hope that works fine for you
for more information check this link and this link

Related

I can't get the attachment from a mail sent in the mail box to the mail box

I made a Python program that sends an attachment to a mailbox which is the main mailbox of my project. The mail is sent from the mailbox itself to the mailbox itself, so it is the same address for the receiver and for the sender. (see on pic)
here is my code which works from attachment that is not coming from the same mailbox. And I just can't get the attachment. Making another mail box is annoying.
import os
from imbox import Imbox
import traceback
host = "imap.gmail.com"
download_folder = "G:\DownloadFMail"
username = "example#gmail.com"
password = "123456"
mail = Imbox(host, username, password, ssl=True, ssl_context=None, starttls=False)
mailAttach = mail.messages(unread=True,sent_from = username)
for (uid, message) in mailAttach:
mail.mark_seen(uid) # optional, mark message as read
for idx, attachment in enumerate(message.attachments):
try:
att_fn = attachment.get('filename')
download_path = f"{download_folder}/{att_fn}"
print(download_path)
with open(download_path, "wb") as fp:
fp.write(attachment.get('content').read())
except:
print(traceback.print_exc())
mail.logout()
Fixed this issue but the cause was coming from the way I send the attachement. Here i was using stmplib to send it but there was not any header for the attachement resulting to this in mail detail :
That's why it was not detected as attachement by Imbox.
Now it look like this and it work perfectly :
and this is the code sample :
with open(zipfile, "rb") as attachment:
payload = MIMEBase('application', 'octate-stream')
payload.set_payload((attachment).read())
encoders.encode_base64(payload) #encode the attachment
payload.add_header('Content-Disposition','attachment',filename="image.zip")
message.attach(payload) here
If it's not clear enough or/and someone need futher explanation ask me.

getting specific xlsx attachment from outlook and saving it on my windows computer

I hope you are well.
I have been doing some python practice with web scraping and have come across the win32com library and have been really struggling to get the attachment from my outlook email ( it is just the one)! I have managed to view all of the emails by the following code. I was wondering if you could help me with getting the attachment file called lets say "data_bay1.xlsx" as i am stumped on the errors. I can so far get the data from the email but i cannot get the attachment xlsx file and the attachment part of the code when i try to run it gives me errors. Please see what I have done so far and I hope any of you can help. I am using anaconda and windows. Thank you in advance! Kind regards, Lily
import win32com.client
#connecting python to outlook
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
#connecting to our inbox
inbox = outlook.GetDefaultFolder(6)
(inbox)
# here we are ensuring the indexes exist so we can grab data
outlook=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
for i in range(50):
try:
box = outlook.GetDefaultFolder(i)
name = box.Name
print(i, name)
except:
pass
messages = inbox.items
messages = messages.GetFirst() earlier
# get the last email
#message = messages.GetLast()
(message)
#to loop through the email in the inbox
while True:
try:
print(message.subject) # get the subject of the email
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
except:
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
# get the attachment
attachments = message.Attachments# return the first item in attachments
attachment = attachments.Item(1)
# the name of attachment file
attachment_name = str(attachment).lower()
attachment.SaveASFile(path+ 'C:\Users\lily\OneDrive - Dataenv\Documents + attachment_data_bay1)
Iterating over all items in the folder is not really a good idea:
#to loop through the email in the inbox
while True:
try:
print(message.subject) # get the subject of the email
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
except:
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
Instead, you need to use the Find/FindNext or Restrict methods of the Items to find items that correspond to your conditions. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
The best you can do is filter the list down to only the items with attachments. For that use PR_HASATTACH (DASL name is http://schemas.microsoft.com/mapi/proptag/0x0E1B000B) MAPI property and then loop through the returned items and process their Attachments collection.

How download attachments from secondary outlook email by Python?

I need download attachment from outlook, but not from my outlook.
I need it from secondary group address (like FiTeam#email.com with pass = asdf).
Right now I have working script that downloading it from my own outlook address.
import os
path = os.path.expanduser("D:\DownloadingEmail\\replenishment")
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
def saveattachemnts(subject):
for message in messages:
if message.Subject.startswith(subject):
# body_content = message.body
attachments = message.Attachments
attachment = attachments.Item(1)
for attachment in message.Attachments:
attachment.SaveAsFile(os.path.join(path, str(attachment)))
if message.Subject == subject and message.Unread:
message.Unread = False
continue
saveattachemnts('Replenishment')
How can I modify it to download the attachment from inbox in FiTeam#email.com?
To access the shared inbox try the following
inbox = outlook.Folders["FiTeam#email.com"].Folders["Inbox"]
also you should fix ("D:\DownloadingEmail\\replenishment") to ("D:\\DownloadingEmail\\replenishment")
SaveAsFile(os.path.join(path, str(attachment) should be SaveAsFile(os.path.join(path, str(attachment.FileName)
message.Unread = False to message.UnRead
see my example code below-
import os
import win32com.client
path = os.path.expanduser("D:\\DownloadingEmail\\replenishment")
print(path)
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders["FiTeam#email.com"].Folders["Inbox"]
messages = inbox.Items
def save_attachments(subject):
for message in messages:
if message.Subject.startswith(subject):
for attachment in message.Attachments:
attachment.SaveAsFile(os.path.join(path, str(attachment.FileName)))
if message.UnRead:
message.UnRead = False
continue
save_attachments('Replenishment')
Call outlook.CreateRecipient("FiTeam#email.com"), then pass the returned Recipient object to outlook.GetSharedDefaultFolder()

Use python to connect to outlook and read emails and attachments then write them to an output file

I am trying to connect to outlook using python and read emails and write them to an output file along with all the corresponding attachments.
This is what I have so far:
import win32com.client
import unicodecsv as csv
import os
output_file = open('./outlook_farming_001.csv','wb')
output_writer = csv.writer(output_file, delimiter=';', encoding='latin2')
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6).Folders.Item("Security Availabilities")
messages = inbox.Items
for i, message in enumerate(messages):
try:
sender = message.SenderName
sender_address = message.SenderEmailAddress
sent_to = message.To
date = message.LastModificationTime
subject = message.subject
body = message.body
attachments = message.Attachments
attachment = attachments.Item(1)
for attachment in message.Attachments:
attachment.SaveAsFile(os.path.join(output_file, str(attachment)))
output_writer.writerow([
sender,
sender_address,
subject,
body,
attachment])
except Exception as e:
()
output_file.close()
Without the attachment stuff in the code- it works fine. I am able to read all the emails from my specific subfolder.
However, I am unable to read, save and display attachments along with their corresponding emails.
I think your mistake is in using str(attachment) in the filename - this will cause trouble because it should give some sort of '<COMObject <unknown>>' string.
Instead, use the following:
for attachment in message.Attachments:
attachment.SaveAsFile(os.path.join(output_file, attachment.FileName))
I hope this helps!

Read all emails from outlook

I wanted to check how can I read all emails from outlook in python
I am using below code, but this code is reading only first mail,
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox. You can change that number to reference
# any other folder
messages = inbox.Items
message = messages.GetLast()
body_content = message.Body
subject = message.Subject
categories = message.Categories
print(body_content)
print(subject)
print(categories)
I tried to find a way so that we can read all emails but unable to get a solution, is anyone know how we can read all emails and store in the database.
You can iterate through the messages object to get all email content.
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
'''message = messages.GetLast()
body_content = message.Body
subject = message.Subject
categories = message.Categories
print(body_content)
print(subject)
print(categories)'''
for message in messages:
print(message.Subject)

Categories

Resources