Read Email From Gmail Using Python

How to Read Email From Gmail Using Python

In this tutorial, you’ll see how to read email from Gmail using Python. In order to accomplish the mail reading task we’ll make use of the imaplib Python module. imaplib is a built in Python module, hence you don’t need to install anything. You simply need to import the module.

You can also use Gmail API to read Email From Gmail Using Python.

How to Login to Gmail Using Python

You need three things to login to Gmail using Python. You’ll need a mail server, a username and password. In this case, since we are trying to login to Gmail, our mail server would be either imap.gmail.com or smtp.gmail.com. If you are trying to read the incoming mail your incoming mail server would be imap.gmail.com and if you are trying to send mail then your outgoing mail server would be smtp.gmail.com. Hence, our mail server is imap.google.com. Username and password are your gmail username and password. Let’s start by writing some code:



ORG_EMAIL   = "@gmail.com"
FROM_EMAIL  = "yourEmailAddress" + ORG_EMAIL
FROM_PWD    = "yourPassword"
SMTP_SERVER = "imap.gmail.com"
SMTP_PORT   = 993

def readmail():
    # mail reading logic will come here !!

In the above code, we have defined our required variables for reading email from Gmail. We have defined the username and password using which we’ll be reading the email and the smpt server address and port number. Let’s use the imap module to login to Gmail using the above credentials.


mail = imaplib.IMAP4_SSL(SMTP_SERVER)
mail.login(FROM_EMAIL,FROM_PWD)

We just used the imap module to connect to the SMTP server over SSL. Using the email address and password defined above we logged  into the email account. I would recommend putting the the whole code inside a try catch block, so that it makes things easy to debug in case something breaks.

Also read : Creating a Web App Using Angular 4

Once we have logged into the email account, we can select the inbox label to read the email.


mail.select('inbox')

Let’s move forward and search the mails in the inbox. It would return a list of ids for each email in the account.


type, data = mail.search(None, 'ALL')
mail_ids = data[0]
id_list = mail_ids.split()

Using the first email id and last email id, we’ll iterate through the email list and fetch each email’s subject and header.


first_email_id = int(id_list[0])
latest_email_id = int(id_list[-1])

Read Email From Gmail Using Python

Let’s iterate through the email and fetch the email with a particular Id. We’ll fetch the email using RFC822 protocol.


typ, data = mail.fetch(i, '(RFC822)' ) # i is the email id

Here is the full code for the Python utility to read emails from Gmail:



import smtplib
import time
import imaplib
import email

# -------------------------------------------------
#
# Utility to read email from Gmail Using Python
#
# ------------------------------------------------

def read_email_from_gmail():
    try:
        mail = imaplib.IMAP4_SSL(SMTP_SERVER)
        mail.login(FROM_EMAIL,FROM_PWD)
        mail.select('inbox')

        type, data = mail.search(None, 'ALL')
        mail_ids = data[0]

        id_list = mail_ids.split()   
        first_email_id = int(id_list[0])
        latest_email_id = int(id_list[-1])


        for i in range(latest_email_id,first_email_id, -1):
            typ, data = mail.fetch(i, '(RFC822)' )

            for response_part in data:
                if isinstance(response_part, tuple):
                    msg = email.message_from_string(response_part[1])
                    email_subject = msg['subject']
                    email_from = msg['from']
                    print 'From : ' + email_from + '\n'
                    print 'Subject : ' + email_subject + '\n'

    except Exception, e:
        print str(e)

Wrapping it Up

In this tutorial, we saw how to read email from Gmail using Python. We used the python module imap to implement the email reading task. Have you ever tried to implement mail reading imap module ? Have you ever encountered any issues trying to read email? Do let us know your thoughts in the comments below.

34 thoughts on “How to Read Email From Gmail Using Python

      1. Yes now i logged
        but there is error here i’m on python 3.5
        typ, data = mail.fetch(i, ‘(RFC822)’)

        Error: . can’t concat bytes to int, line 33

        1. I got around that by changing the code to this:

          typ, data = mail.fetch(str.encode(str(i)), ‘(RFC822)’ )

          but now I got a different error: initial_value must be str or None, not bytes

    1. instead of iterating from last to first ID, just do a single mail.fetch(latest_email_id, ‘(RFC822)’ )
      if that doesn’t work (like I tried in Python 3.6.3) you might need to encode the id to byte (as the fetch is looking for byte type):
      mail.fetch(str.encode(str(latest_email_id)), ‘(RFC822)’ )
      or
      mail.fetch(bytes(str(latest_email_id), ‘utf-8’ ), ‘(RFC822)’ )

      That, or simply don’t convert the latest_email_id to int, which is much cleaner.

  1. I have implemented this code and get a google warning:

    mail.login(FROM_EMAIL,FROM_PWD)
    File “C:…imaplib.py”, line 582, in login
    raise self.error(dat[-1])
    imaplib.error: b'[ALERT] Please log in via your web browser: https://support.google.com/mail/accounts/answer/78754 (Failure)’

    i.e. Google wants me to use an app that has enhanced security–not python code.

    Other discussions group say to “Go to the “Less secure apps” section in My Account.” on gmail and enable less secure apps.
    Did that, and still getting the above message.

    Do you know any work arounds or code changes we can make to your code above?

      1. I tried both of these and it didn’t work, I still have this exact same problem. Any idea why? Am connecting from the UK, don’t know if it makes any difference.

        1. I faced the same issue when connecting over a remote server that was in the US. I got an email from google security alerts about this “suspicious” activity. Once I unflagged it, I was able to get this to work.

    1. The cause of this error is the Google Account Security that is, Google provides security options to secure your account from unidentified third party applications or less secure applications, and this security option is enabled by default.
      To resolve this error, just log into your google account, and visit this link https://myaccount.google.com/security , or you can also manually navigate to this link as
      gmail account > click on Profile Image (at top right corner) > My Account > click on Connected apps & sites link.

      now scroll down to “Connected Apps & Sites” section and enable “Allow less secure apps” option.
      That’s it.

    1. Not directly. Some modification is required. Here’s how I got it working:

      def read_email_from_gmail():
      try:
      mail = imaplib.IMAP4_SSL(SMTP_SERVER)
      mail.login(FROM_EMAIL,FROM_PWD)
      mail.select(‘inbox’)

      type, data = mail.search(None, ‘ALL’)
      mail_ids = data[0]

      id_list = mail_ids.split()

      for i in reversed(id_list):
      typ, data = mail.fetch(i, ‘(RFC822)’ )

      for response_part in data:
      if isinstance(response_part, tuple):
      msg = email.message_from_string(response_part[1].decode(‘utf-8’))
      email_subject = msg[‘subject’]
      email_from = msg[‘from’]
      print(‘From : ‘ + email_from + ‘n’)
      print(‘Subject : ‘ + email_subject + ‘n’)

      except Exception as e:
      print(str(e))

      MY CHANGES are:
      – Removed the first/last ID – it’s not needed.
      – changed the for loop to iterate over reversed(id_list) instead, the original doesn’t include the first ID and the first/last IDs are meaningless if you’re iterating the whole list.
      – added the .decode(‘utf-8’) to response_part[1] in the msg =… line to decode from byte to string

      NOTE: If you want to get the body of the message (like I want to) you’ll need to iterate over msg.get_payload()

        1. The code extracts emails but it doesn’t pull all emails for the seacrh condition. Example: maibox has 1300 emails by same sender but it only pulls 676. any suggestions ?

    1. It’s just a function, it’s not called. Try adding the line ‘def read_email_from_gmail()’ to the end.

  2. Thanks for the tutorial. It was helpful. But on python3, it shows up errors. Below is an example working code with tweaks. Note that it will only print the subject.

    def read_email_from_gmail():
    # try:
    mail = imaplib.IMAP4_SSL(SMTP_SERVER)
    mail.login(FROM_EMAIL,FROM_PWD)
    mail.select(‘inbox’)

    type, data = mail.search(None, ‘ALL’)
    mail_ids = data[0]

    id_list = mail_ids.split()
    first_email_id = int(id_list[0])
    latest_email_id = int(id_list[-1])

    for i in range(latest_email_id,first_email_id, -1):
    typ, data = mail.fetch(str(i), ‘(RFC822)’ )

    for response_part in data:
    if isinstance(response_part, tuple):
    msg = email.message_from_string(response_part[1].decode())
    email_subject = msg[‘subject’]
    email_from = msg[‘from’]
    print(email_subject)
    # print ‘From : ‘ + email_from + ‘n’
    # print ‘Subject : ‘ + email_subject + ‘n’

    # except Exception as e:
    # print(str(e))

  3. type, data = mail.search(None, ‘ALL’)

    This line breaks the type() function. This should be revised to something like

    response, data = mail.search(None, ‘ALL’)

  4. am getting this error:

    Traceback (most recent call last):
    File “em.py”, line 2, in
    import smtplib
    File “/usr/lib/python2.7/smtplib.py”, line 46, in
    import email.utils
    File “/home/charan/charan/email.py”, line 5, in
    mail= imaplib.IMAP4_SSL(‘imap.gamil.com’,993)
    File “/usr/lib/python2.7/imaplib.py”, line 1168, in __init__
    IMAP4.__init__(self, host, port)
    File “/usr/lib/python2.7/imaplib.py”, line 173, in __init__
    self.open(host, port)
    File “/usr/lib/python2.7/imaplib.py”, line 1179, in open
    self.sock = socket.create_connection((host, port))
    File “/usr/lib/python2.7/socket.py”, line 557, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    socket.gaierror: [Errno -2] Name or service not known

  5. how to make it read one newest email from a single email adrr + i wanted to print the body msg of that latest email

Leave a Reply

Your email address will not be published. Required fields are marked *