Skip to content

Instantly share code, notes, and snippets.

Created April 1, 2019 06:01
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save PandaWhoCodes/f7adce3bff9bb1f508b3ab42db05a6bf to your computer and use it in GitHub Desktop.
A script to download emails from gmail -
import imaplib
import email
import os
def create_folder(folder_name="backup"):
Creates a folder to store all mails
if not os.path.exists(folder_name):
def extract_body(payload):
returns the email body from the payload
if isinstance(payload, str):
return payload
return '\n'.join([extract_body(part.get_payload()) for part in payload])
def create_connection(user_name, password):
logs into the email service provider using the provided username and password
:return: connection object for imaplib
conn = imaplib.IMAP4_SSL("", 993)
conn.login(user_name, password)
except Exception as e:
print("Could not login", e)
return conn
def show_mailBoxes(conn):
Displays the mail boxes in your email client
:param conn: imaplib object
mailboxes = []
for n, item in enumerate(conn.list()[1]):
mailbox = item.decode("utf-8")
mailboxes.append(mailbox[mailbox.index("\"/\"") + 4:])
print(n, mailbox[mailbox.index("\"/\"") + 4:])
return mailboxes
def select_mailbox(conn, mailbox):
select a mailbox to search through
:param conn: imaplib object
:param mailbox: name of the mailbox
def save_email(num, subject, body):
with open("backup/" + str(num.decode('utf-8')) + ".txt", "w") as f:
def get_emails(conn, search_param):
count = 0
typ, data =, search_param)
for num in data[0].split():
_, msg_data = conn.fetch(num, '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1].decode("utf-8"))
subject = msg['subject']
payload = msg.get_payload()
body = extract_body(payload)
save_email(num, subject, body)
count += 1
if count % 100 == 0:
print(count, "Messages saved")
except Exception as e:
print("Couldnt Parse message:", num, e)
except Exception as e:
if __name__ == '__main__':
conn = create_connection("", "password")
mailboxes = show_mailBoxes(conn)
mailbox_choice = int(input("Select a mailbox: "))
select_mailbox(conn, mailboxes[mailbox_choice])
search_param = input("Enter the filter- Leave blank for ALL")
if len(search_param) == 0:
search_param = "ALL"
get_emails(conn, search_param)
Copy link

What do you mean by filter over here?

Copy link

Also do you know how to move something from spam to inbox?

Copy link

hongyi-zhao commented Aug 21, 2021

I tried with your above script, but meet the following error:

$ python 
1 "Junk"
2 "[Gmail]"
3 "[Gmail]/All Mail"
4 "[Gmail]/Drafts"
5 "[Gmail]/Important"
6 "[Gmail]/Sent Mail"
7 "[Gmail]/Spam"
8 "[Gmail]/Starred"
9 "[Gmail]/Trash"
10 "&XeVPXJCuTvY-"
11 "&ZTZjbg-"
12 "&ZcWITHb4UXM-"
13 "&ecFOupCuTvY-"
Select a mailbox: 0
Enter the filter- Leave blank for ALL
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1047, in _command_complete
    typ, data = self._get_tagged_response(tag, expect_bye=logout)
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1173, in _get_tagged_response
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1075, in _get_response
    resp = self._get_line()
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1183, in _get_line
    line = self.readline()
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 325, in readline
    raise self.error("got more than %d bytes" % _MAXLINE)
imaplib.error: got more than 1000000 bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/werner/", line 108, in <module>
    get_emails(conn, search_param)
  File "/home/werner/", line 73, in get_emails
    typ, data =, search_param)
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 734, in search
    typ, dat = self._simple_command(name, *criteria)
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1230, in _simple_command
    return self._command_complete(name, self._command(name, *args))
  File "/home/werner/.pyenv/versions/3.9.1/lib/python3.9/", line 1051, in _command_complete
    raise self.error('command: %s => %s' % (name, val))
imaplib.error: command: SEARCH => got more than 1000000 bytes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment