Python脚本无法定位目标文件且重复发送邮件问题求助
Hey there! Let's tackle your two issues—missing file detection and duplicate emails—step by step.
The core problem here is how you're checking for the file's existence. Right now, you use os.path.exists(master) where master is just a filename (like "XXX Master Box File List.xls"), but this checks your script's current working directory, not the specific jobfolder you're iterating over.
You need to build the full path to the file by combining the base bureau directory, the target jobfolder, and the filename. Here's the fix:
# Replace your existing master path check with this master_filename = ' '.join([jnum, "Master Box File List.xls"]) # Build the full, absolute path to the file in the job folder master_full_path = os.path.join(bureau, jobfolder, master_filename) if os.path.exists(master_full_path): print(master_full_path) else: # Trigger email logic here
Your email code is nested inside two nested loops: the os.walk loop and the for jobfolder in os.listdir(bureau) loop. Every time the script hits a missing file in any iteration, it sends an email—hence the duplicates.
Fix this by adding a flag to track if you've already sent the email, and only send it once. Here's the adjusted full code with this logic (plus other small improvements):
import os import smtplib import time from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText bureau = "/path/to/your/bureau/directory" # Confirm this path is correct! jobnums = ["your", "target", "job", "numbers"] # Your existing jobnums list email_sent = False # Flag to prevent duplicate emails for path, dirs, files in os.walk(bureau): for filename in files: filename_no_ext, ext = os.path.splitext(filename) if ext.lower() == '.xls': num = filename.rsplit(" ") if len(num) < 1: # Add safety check to avoid index errors continue jnum = num[0] if jnum in jobnums: master_filename = ' '.join([jnum, "Master Box File List.xls"]) for jobfolder in os.listdir(bureau): jobfolder_path = os.path.join(bureau, jobfolder) # Skip non-directory entries in bureau if os.path.isdir(jobfolder_path) and jobfolder.startswith(jnum): master_full_path = os.path.join(jobfolder_path, master_filename) # Only trigger email if file is missing AND email hasn't been sent yet if not os.path.exists(master_full_path) and not email_sent: fromaddr = "your-email@gmail.com" toaddr = "recipient-email@example.com" max_attempts = 5 login_success = False for i in range(max_attempts): try: msg = MIMEMultipart() msg['From'] = fromaddr msg['To'] = toaddr msg['Subject'] = "Scripting Email" body = "This email is an automatic email part of a Python training exercise" msg.attach(MIMEText(body, 'plain')) server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(fromaddr, "your-app-password") # Use app password if 2FA is enabled text = msg.as_string() print("Signed In To Mailbox.") login_success = True break except Exception as e: # Catch specific errors for easier debugging print(f"Can't Sign In To Mailbox. Error: {str(e)}. Trying Again....") time.sleep(0.5) continue if login_success: server.sendmail(fromaddr, toaddr, text) server.quit() print("Email Sent.") email_sent = True # Mark email as sent to stop duplicates else: print("Can't Sign In To Mailbox.") elif os.path.exists(master_full_path): print(f"Found target file: {master_full_path}")
Quick Extra Tips
- Added
os.path.isdir(jobfolder_path)to skip any files in thebureaudirectory (sinceos.listdirreturns both files and folders). - Replaced the bare
exceptwithexcept Exception as eto catch and print specific errors—this will help you debug login issues if they arise. - If you have 2FA enabled on your Gmail account, you'll need to use an app password instead of your regular account password.
内容的提问来源于stack exchange,提问作者Harry Adkins

