如何从 Gmail 读取电子邮件?

gwc*_*gwc 8 python email gmail

我正在尝试将我的 gmail 连接到 python,但显示此错误:

我已经检查过我的密码,知道是什么吗?

b'[AUTHENTICATIONFAILED] Invalid credentials (Failure)'
Traceback (most recent call last):
  File "/Users/myuser/Documents/migrations/untitled3.py", line 29, in read_email_from_gmail
    mail.login(FROM_EMAIL,FROM_PWD)
  File "/Users/myuser/opt/anaconda3/lib/python3.9/imaplib.py", line 612, in login
    raise self.error(dat[-1])
imaplib.IMAP4.error: b'[AUTHENTICATIONFAILED] Invalid credentials (Failure)'
Run Code Online (Sandbox Code Playgroud)

这是我的代码:我还想知道我可以使用哪个端口?

import smtplib
import time
import imaplib
import email
import traceback 

ORG_EMAIL = "@gmail.com" 
FROM_EMAIL = "myemail" + ORG_EMAIL 
FROM_PWD = "mypassword" 
SMTP_SERVER = "smtp.gmail.com" 
SMTP_PORT = ??

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

        data = mail.search(None, 'ALL')
        mail_ids = data[1]
        id_list = mail_ids[0].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):
            data = mail.fetch(str(i), '(RFC822)' )
            for response_part in data:
                arr = response_part[0]
                if isinstance(arr, tuple):
                    msg = email.message_from_string(str(arr[1],'utf-8'))
                    email_subject = msg['subject']
                    email_from = msg['from']
                    print('From : ' + email_from + '\n')
                    print('Subject : ' + email_subject + '\n')

    except Exception as e:
        traceback.print_exc() 
        print(str(e))

read_email_from_gmail()
Run Code Online (Sandbox Code Playgroud)

我的主要目标是能够从每封电子邮件中获取 CSV 文件,但现在我只想阅读消息。

小智 16

阅读电子邮件的最佳方式是使用 GMAIL API。从 2022 年 5 月 30 日起,Google 已停止通过任何外部应用程序使用用户名和密码访问 gmail 帐户。这就是从 python 读取 gmail 的方式。

这个应用程序的作用:

  • 阅读 Gmail 消息(未读)
  • 阅读消息后将消息设为已读
import os.path
import base64
import json
import re
import time
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import logging
import requests

SCOPES = ['https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.modify']

def readEmails():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(               
                # your creds file here. Please create json file as here https://cloud.google.com/docs/authentication/getting-started
                'my_cred_file.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    try:
        # Call the Gmail API
        service = build('gmail', 'v1', credentials=creds)
        results = service.users().messages().list(userId='me', labelIds=['INBOX'], q="is:unread").execute()
        messages = results.get('messages',[]);
        if not messages:
            print('No new messages.')
        else:
            message_count = 0
            for message in messages:
                msg = service.users().messages().get(userId='me', id=message['id']).execute()                
                email_data = msg['payload']['headers']
                for values in email_data:
                    name = values['name']
                    if name == 'From':
                        from_name= values['value']                
                        for part in msg['payload']['parts']:
                            try:
                                data = part['body']["data"]
                                byte_code = base64.urlsafe_b64decode(data)

                                text = byte_code.decode("utf-8")
                                print ("This is the message: "+ str(text))

                                # mark the message as read (optional)
                                msg  = service.users().messages().modify(userId='me', id=message['id'], body={'removeLabelIds': ['UNREAD']}).execute()                                                       
                            except BaseException as error:
                                pass                            
    except Exception as error:
        print(f'An error occurred: {error}')
Run Code Online (Sandbox Code Playgroud)

您需要在 Google 帐户中创建凭证文件 如何在此处创建凭证文件https://cloud.google.com/docs/authentication/getting-started


小智 5

问题是,Gmail 有一个新的政策,不允许使用不安全的应用程序。

\n
\n

为了确保您帐户的安全,从 2022 年 5 月 30 日起,\xe2\x80\x8b\xe2\x80\x8bGoogle 不再支持使用要求您仅使用您的帐户登录 Google 帐户的第三方应用或设备。用户名和密码。

\n
\n


小智 2

  1. 如果您要以这种方式进行检查,则需要在 Gmail 帐户中启用“安全性较低的应用程序” 。因此,最好使用Gmail API

  2. 未设置 SMTP 端口 - 确保您使用正确的端口(993)

  • 请注意,此“安全性较低的应用程序”选项不再可用(从 2022 年 5 月起)。 (5认同)