Learning The POP3 Protocol
Learning The POP3 Protocol
POP3 is designed to receive emails, not to send them; it allows users with
intermittent or very slow connections (such as modem connections) to download
their emails while they have a connection and later check them when they are
disconnected. It should be mentioned that most mail clients include the option to
leave messages on the server so that a client using POP3 connects, obtains all
messages, stores them on the user's computer as new messages, removes them
from the server, and finally disconnects.
The following diagram shows the client and server communicating through the
POP3 protocol:
The client establishes a connection to the server on TCP port 110. They then send
their username and password to access the mailbox. Once the connection has
been established, the user can obtain the email messages individually.
If you want to read a little more, here is a link to your corresponding RFC: https://tools.ietf.org/
html/rfc1725.html.
Introduction to poplib
Accessing an email address from Python is very simple if you have POP3
enabled. For this task, can use the poplib library. As an example, I will use Gmail.
If you want to try this out for yourself, remember to enable POP3 on the Gmail
website. To do this, you need to enter the configuration section inside a Gmail
account. You can review Gmail account configuration section of this part.
POP()
POP3_SSL()
Both classes implement the POP3 and POP3S protocols, respectively. The class
constructor for each one accepts three arguments: host, port, and timeout. The
optional timeout parameter determines the number of seconds of the connection
timeout at the server.
Basically, this module will allow us to connect to a POP3 server, and then
authenticate and read the emails. In addition, this module provides a POP3_SSL
class, which provides support for connecting to POP3 servers that use SSL as the
underlying protocol layer.
We can retrieve all of the messages from an email account with the retr method. The following
link provides documentation about this method: https://docs.python.org/3/library/poplib.html#poplib.POP3
.retr.
Here is a minimal example that opens a mailbox and retrieves all of its
messages. First, we create a POP3_SSL object (Gmail works with SSL) and enter
our username and password. From here, we can manage our emails with the
functions that are provided by the poplib library. In this example, we obtain the
list of messages with the list() method. The last message is chosen from the
response and the server is requested through retr(msgid).
import poplib
mailbox = poplib.POP3_SSL("pop.gmail.com",995)
mailbox.user("user")
mailbox.pass_("password")
print(mailbox.getwelcome())
messages = len(mailbox.list()[1])
mailbox.quit()
In this example, we have the same functionality from the previous script—the
only difference is how we get the params server, port, user, and password from the
command line.
import poplib
import argparse
def main(hostname,port,user,password):
mailbox = poplib.POP3_SSL(hostname,port)
try:
mailbox.user(user)
mailbox.pass_(password)
response, listings, octet_count = mailbox.list()
for listing in listings:
number, size = listing.decode('ascii').split()
print("Message %s has %s bytes" % (number, size))
except poplib.error_proto as exception:
print("Login failed:", exception)
finally:
mailbox.quit()
In the previous code block we have defined our function that accepts as
parameters the hostname,port,user and password and establish the connection
with this configuration.In the next code block we use the argparse module for
setting the parameters used by the main() method.
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='MailBox basic params')
parser.add_argument('--hostname', action="store", dest="hostname")
parser.add_argument('--port', action="store", dest="port")
parser.add_argument('--user', action="store", dest="user")
given_args = parser.parse_args()
hostname = given_args.hostname
port = given_args.port
user = given_args.user
import getpass
password = getpass.getpass(prompt='Enter your password:')
main(hostname,port,user,password)
Let's see how we can read out the email messages by accessing Google's secure
POP3 email server. By default, the POP3 server listens on port 995 securely. The
following is an example of fetching an email by using POP3.
import poplib
import getpass
mailbox.user(username)
mailbox.pass_(password)
EmailInformation = mailbox.stat()
print("Number of new emails: %s ", EmailInformation)
numberOfMails = EmailInformation[0]
num_messages = len(mailbox.list()[1])
In the previous code block we initialize the connection with pop3 server mail
and store information about connection in mailbox object, later we get
information about stats and the messages number. In the next code block we use
the mailbox object to retrieve information about each message contained in the
mailbox.
for i in range (num_messages):
print("\nMessage number "+str(i+1))
print("--------------------")
# read message
response, headerLines, bytes = mailbox.retr(i+1)
#for header in headerLines:
#print(str(header))
print('Message ID', headerLines[1])
print('Date', headerLines[2])
print('Reply To', headerLines[4])
print('To', headerLines[5])
print('Subject', headerLines[6])
print('MIME', headerLines[7])
print('Content Type', headerLines[8])
mailbox.quit()
In this example we have extracted mails from our mailbox server using the list()
method.For each message we can print all information available in headerLines
array .Also we can get information in that array accessing specific index
like headerLines[1] for get Message ID or headerLines[5] for get mail
destination.
Establishing a connection with Gmail
for reading emails
Now, we are going to go into detail regarding the code of the previous script. For
reading, we first establish the connection to the Gmail pop server, using
the getpass module to request the password:
# Connection is established with the gmail pop server
mailbox = poplib.POP3_SSL ('pop.gmail.com', 995)
import getpass
username = input('Enter your username:')
password = getpass.getpass(prompt='Enter your password:')
mailbox.user(username)
mailbox.pass_(password)
Here, we used poplib.POP3_SSL, passing the name of the server, that is, pop.gmail.com,
and the connection port, 995. Then, we have set the username and password of
Gmail. The method to do this is pass_(), with an underscore at the end.
Gmail account configuration
In the POP/IMAP configuration of your account, you can find the following
options.
In the following screenshot, we can see the Gmail settings page for the POP
protocol:
In the Settings page, you can configure the POP protocol and enable it for all
emails or only emails that arrive from now on.
Unread messages
To see how many unread messages you have, you can call the list() method
from the mailbox object. Use the following code to find out how many unread
messages you have:
number_messages = len(mailbox.list()[1])
With this, we just have to loop and get the messages one by one to analyze them:
for i in range (num_messages):
print("Message number "+str(i+1))
print("--------------------")
# read message
response, headerLines, bytes = mailbox.retr(i+1)
The retr(i+1) method brings the message from the server whose number is
indicated and marks it on the server as read. It is set to i+1 because the retr()
method starts at 1 and not at zero. This method returns the server response, the
message, and a few bytes related to the message that we are reading. The
important thing is headerLines, which in some way contains all of the lines of the
message.