Python无法连接Gmail IMAP服务器:新手求助实现邮件通知功能
Hey there! As someone new to programming, it's totally normal to hit roadblocks with authentication and script logic—let's get this working for you step by step. The main issue here is Gmail's modern authentication requirements, plus a few small bugs in your code.
1. Core Authentication Problem (Why You Can't Connect)
Google no longer allows regular account passwords for IMAP access for personal Gmail accounts. The easiest fix for beginners is to use an App Password:
- First, make sure you have 2-Step Verification turned on for your Google account.
- Go to your Google Account's Security page, find "App Passwords" under "Signing in to Google", generate a 16-character app password, and use THAT instead of your regular Gmail password in the script.
If you can't use App Passwords (e.g., no 2-Step Verification), you'd need to set up OAuth2 authentication—but that's more complex, so let's stick with App Passwords first.
2. Fixing the Code Bugs
Your script has several small issues that would break functionality even if authentication worked:
- Broken file path:
"%sytemdrive%"is a typo (should be%SystemDrive%), and you need to use raw strings or escaped backslashes in Python to avoid path errors. - Missing parentheses on
file.close(it's a function call, so needsfile.close()). - Incomplete
subprocess.callcommand (truncated and parameter order is wrong). - No delay in the loop (will spam the IMAP server and eat up CPU).
- No error handling for cases like IMAP disconnections or missing files.
3. Working Revised Code
Here's the fixed version with comments explaining key changes:
import imaplib import re import time import subprocess import os # Account details (replace with your info) imapServer = "imap.gmail.com" port = 993 # Use integer instead of string for port username = "example@gmail.com" # Use your generated 16-character App Password here! password = "your-app-password-here" # Check interval in seconds (2 minutes is reasonable to avoid rate limits) checkInterval = 120 # Fix temp file path (use raw string + expand environment variable) temp_file_path = r"%SystemDrive%\Windows\Temp\mailnotify.tmp" temp_file_path = os.path.expandvars(temp_file_path) def get_unread_count(mailbox): """Safely fetch unread email count with error handling""" try: rc, message = mailbox.status('INBOX', "(UNSEEN)") if rc != 'OK': raise Exception("Failed to fetch inbox status") match = re.search(r"UNSEEN (\d+)", str(message[0])) return int(match.group(1)) if match else 0 except Exception as e: print(f"Error getting unread count: {e}") return 0 try: # Connect to IMAP server Mailbox = imaplib.IMAP4_SSL(imapServer, port) rc, resp = Mailbox.login(username, password) if rc != 'OK': raise Exception(f"Login failed: {resp}") print(f"Connected to {imapServer} successfully!") # Initialize temp file with current unread count initial_unread = get_unread_count(Mailbox) with open(temp_file_path, "w") as file: file.write(str(initial_unread)) oldValue = initial_unread print(f"Initial unread emails: {initial_unread}") # Main loop to check for new emails while True: current_unread = get_unread_count(Mailbox) # Read old count from temp file (handle missing/invalid file) try: with open(temp_file_path, "r") as file: oldValue = int(file.readline().strip()) except (FileNotFoundError, ValueError): oldValue = current_unread with open(temp_file_path, "w") as file: file.write(str(oldValue)) # Trigger notification if new emails arrive if current_unread > oldValue: new_emails = current_unread - oldValue # Fix notify-send command (correct parameter order) subprocess.call([ "notify-send", "-u", "low", "-t", "5000", "New Gmail Alert!", f"You have {new_emails} new unread email(s)!" ]) # Update temp file with latest count with open(temp_file_path, "w") as file: file.write(str(current_unread)) oldValue = current_unread print(f"New email(s) detected: {new_emails}") # Wait before next check time.sleep(checkInterval) except Exception as e: print(f"Script error: {e}") finally: # Clean up IMAP connection if 'Mailbox' in locals(): Mailbox.logout()
4. Windows Compatibility Note
If you're running this on Windows, notify-send won't work—it's a Linux tool. Replace the notification section with this Windows-native alternative (first install win10toast via pip install win10toast):
from win10toast import ToastNotifier toaster = ToastNotifier() toaster.show_toast( "New Gmail Alert!", f"You have {new_emails} new unread email(s)!", duration=5 )
内容的提问来源于stack exchange,提问作者Jonathan Ej

