1
votes

Comment recevoir des e-mails de gmail python?

Je veux obtenir les 10 derniers gmails reçus avec python.

Actuellement, j'ai ce code mais il ne renvoie qu'un nombre limité d'e-mails et il manipule directement pop3, ce qui le rend inutile.

Source du code: https://www.code-learner.com/python-use-pop3-to-read-email-example/

import poplib
from email import parser
pop_conn = poplib.POP3_SSL('pop.gmail.com')
pop_conn.user('@gmail.com')
pop_conn.pass_('password')

messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message intom an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
    print(message['subject'])
    print(message['body'])

J'ai également essayé ce code mais cela n'a pas fonctionné:

import imaplib, email, base64


def fetch_messages(username, password):
    messages = []
    conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
    conn.login(username, password)
    conn.select()
    typ, data = conn.uid('search', None, 'ALL')

    for num in data[0].split():
        typ, msg_data = conn.uid('fetch', num, '(RFC822)')
        for response_part in msg_data:
            if isinstance(response_part, tuple):
                messages.append(email.message_from_string(response_part[1]))
        typ, response = conn.store(num, '+FLAGS', r'(\Seen)')
    return messages

et cela n'a pas non plus fonctionné pour moi ...

import poplib
import smtplib, ssl
def guess_charset(msg):
    # get charset from message object.
    charset = msg.get_charset()
    # if can not get charset
    if charset is None:
       # get message header content-type value and retrieve the charset from the value.
       content_type = msg.get('Content-Type', '').lower()
       pos = content_type.find('charset=')
       if pos >= 0:
          charset = content_type[pos + 8:].strip()
    return charset

def decode_str(s):
    value, charset = decode_header(s)[0]
    if charset:
       value = value.decode(charset)
    return value
# variable indent_number is used to decide number of indent of each level in the mail multiple bory part.
def print_info(msg, indent_number=0):
    if indent_number == 0:
       # loop to retrieve from, to, subject from email header.
       for header in ['From', 'To', 'Subject']:
           # get header value
           value = msg.get(header, '')
           if value:
              # for subject header.
              if header=='Subject':
                 # decode the subject value
                 value = decode_str(value)
              # for from and to header. 
              else:
                 # parse email address
                 hdr, addr = parseaddr(value)
                 # decode the name value.
                 name = decode_str(hdr)
                 value = u'%s <%s>' % (name, addr)
           print('%s%s: %s' % (' ' * indent_number, header, value))
    # if message has multiple part. 
    if (msg.is_multipart()):
       # get multiple parts from message body.
       parts = msg.get_payload()
       # loop for each part
       for n, part in enumerate(parts):
           print('%spart %s' % (' ' * indent_number, n))
           print('%s--------------------' % (' ' * indent_number))
           # print multiple part information by invoke print_info function recursively.
           print_info(part, indent_number + 1)
    # if not multiple part. 
    else:
        # get message content mime type
        content_type = msg.get_content_type() 
        # if plain text or html content type.
        if content_type=='text/plain' or content_type=='text/html':
           # get email content
           content = msg.get_payload(decode=True)
           # get content string charset
           charset = guess_charset(msg)
           # decode the content with charset if provided.
           if charset:
              content = content.decode(charset)
           print('%sText: %s' % (' ' * indent_number, content + '...'))
        else:
           print('%sAttachment: %s' % (' ' * indent_number, content_type))

# input email address, password and pop3 server domain or ip address
email = 'yourgmail@gmail.com'
password = 'yourpassword'

# connect to pop3 server:
server = poplib.POP3_SSL('pop.gmail.com')
# open debug switch to print debug information between client and pop3 server.
server.set_debuglevel(1)
# get pop3 server welcome message.
pop3_server_welcome_msg = server.getwelcome().decode('utf-8')
# print out the pop3 server welcome message.
print(server.getwelcome().decode('utf-8'))

# user account authentication
server.user(email)
server.pass_(password)

# stat() function return email count and occupied disk size
print('Messages: %s. Size: %s' % server.stat())
# list() function return all email list
resp, mails, octets = server.list()
print(mails)

# retrieve the newest email index number
#index = len(mails)
index = 3
# server.retr function can get the contents of the email with index variable value index number.
resp, lines, octets = server.retr(index)

# lines stores each line of the original text of the message
# so that you can get the original text of the entire message use the join function and lines variable. 
msg_content = b'\r\n'.join(lines).decode('utf-8')
# now parse out the email object.

from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr

import poplib

# parse the email content to a message object.
msg = Parser().parsestr(msg_content)
print(len(msg_content))
# get email from, to, subject attribute value.
email_from = msg.get('From')
email_to = msg.get('To')
email_subject = msg.get('Subject')
print('From ' + email_from)
print('To ' + email_to)
print('Subject ' + email_subject)
for part in msg.walk():
    if part.get_content_type():
        body = part.get_payload(decode=True)
        print_info(msg, len(msg))


# delete the email from pop3 server directly by email index.
# server.dele(index)
# close pop3 server connection.
server.quit()


1 commentaires

Si vous voulez des e-mails de gmail, vous souhaitez probablement utiliser l'api: développeurs.google.com/ gmail/api


3 Réponses :


1
votes

Vous devriez essayer easyimap lib pour obtenir une liste d'e-mails, je ne sais pas si cela fonctionne avec pop3.

Exemple de code:

import easyimap

host = 'imap.gmail.com'
user = 'you@example.com'
password = 'secret'
mailbox = 'INBOX.subfolder'
imapper = easyimap.connect(host, user, password, mailbox)

email_quantity = 10
emails_from_your_mailbox = imapper.listids(limit=email_quantity)
imapper.quit()


1 commentaires

Pouvez-vous m'aider? le code m'a donné une erreur: Exception: Timeout et quand je change imapper = easyimap.connect(host, user, password, mailbox) pour imapper = easyimap.connect(host, user, password, mailbox, ssl=Fals e, port=143) il dit: imaplib.abort: erreur de socket: EOF.



1
votes

J'ai réussi à le résoudre, le seul problème est qu'il marque comme lu chaque email non lu, voici le code que j'ai utilisé:

import imaplib

mail = imaplib.IMAP4_SSL('imap.gmail.com')
email = input('Email: ')
password = input('Password: ')
mail.login(email+'@gmail.com', password)
mail.list()
# Out: list of "folders" aka labels in gmail.
mail.select("inbox") # connect to inbox.
result, data = mail.search(None, "ALL")

ids = data[0] # data is a list.
id_list = ids.split() # ids is a space separated string
latest_email_id = id_list[-1] # get the latest

# fetch the email body (RFC822) for the given ID
result, data = mail.fetch(latest_email_id, "(RFC822)") 

raw_email = data[0][1] # here's the body, which is raw text of the whole email
# including headers and alternate payloads

import email
email_message = email.message_from_string(str(raw_email))
 
print (email_message['To'])
 
print (email.utils.parseaddr(email_message['From'])) # for parsing "Yuji Tomita" <yuji@grovemade.com>
 
print (email_message.items()) # print all headers
 
# note that if you want to get text content (body) and the email contains
# multiple payloads (plaintext/ html), you must parse each message separately.
# use something like the following: (taken from a stackoverflow post)
def get_first_text_block(self, email_message_instance):
    maintype = email_message_instance.get_content_maintype()
    if maintype == 'multipart':
        for part in email_message_instance.get_payload():
            if part.get_content_maintype() == 'text':
                return part.get_payload()
    elif maintype == 'text':
        return email_message_instance.get_payload()


0 commentaires

1
votes

https://developers.google.com/gmail/api/quickstart/python est le moyen préféré:

def ListThreadsMatchingQuery(service, user_id='me', query=''):
  """List all Threads of the user's mailbox matching the query.

  Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    query: String used to filter messages returned.
           Eg.- 'label:UNREAD' for unread messages only.

  Returns:
    List of threads that match the criteria of the query. Note that the returned
    list contains Thread IDs, you must use get with the appropriate
    ID to get the details for a Thread.
  """
  try:
    response = service.users().threads().list(userId=user_id, q=query).execute()
    threads = []
    if 'threads' in response:
      threads.extend(response['threads'])

    while 'nextPageToken' in response:
      page_token = response['nextPageToken']
      response = service.users().threads().list(userId=user_id, q=query,
                                        pageToken=page_token).execute()
      threads.extend(response['threads'])

    return threads
  except errors.HttpError as error:
    raise error

où:

from gmail.gmail import gmail_auth, ListThreadsMatchingQuery

service = gmail_auth()
threads = ListThreadsMatchingQuery(service, query=query)


0 commentaires