使用Python调度器实现自动邮件发送时遇socket.gaierror错误求助
修复建议
结合你遇到的 socket.gaierror: [Errno -3] Temporary failure in name resolution 错误,以及代码中的问题,以下是具体修复方案:
1. 修正语法错误
- 无效函数名:
Email CreationSending包含空格,不符合Python命名规范,改为email_creation_sending - 拼写错误:
zipfile.ZipFie应为zipfile.ZipFile - 方法调用遗漏括号:
smtpObj.quit改为smtpObj.quit(),否则SMTP连接无法正确关闭
2. 解决调度逻辑冲突
你同时混用了 schedule 库的装饰器 @repeat(every(30).seconds) 和 schedule.every().second.do(),导致同一任务被重复注册,引发任务并发执行,进而导致网络请求过于频繁,触发DNS解析失败。二选一即可,推荐保留一种调度方式:
- 若需每30秒执行一次,使用装饰器方式;
- 若需每秒执行,使用
do()方法(不建议每秒发邮件,易触发邮件服务商限制)。
3. 优化网络连接管理
单独运行邮件代码正常,但调度重复执行时,未正确关闭的SMTP连接会耗尽网络资源,间接引发DNS解析问题。建议用 with 语句管理SMTP连接,确保自动关闭:
import smtplib with smtplib.SMTP_SSL('smtp.example.com', 465) as smtpObj: smtpObj.login('your_email', 'your_password') # 发送邮件逻辑
4. 修正后的简化代码示例
import time import schedule import os import zipfile import shutil import smtplib from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders def zipdir(path, ziph): for root, dirs, files in os.walk(path): for file in files: file_path = os.path.join(root, file) ziph.write(file_path, os.path.relpath(file_path, path)) def email_creation_sending(): # 压缩目录 with zipfile.ZipFile('file.zip', 'w', zipfile.ZIP_DEFLATED) as zipf: zipdir('directory', zipf) # 构建邮件并发送(用with管理SMTP连接) msg = MIMEMultipart() msg['From'] = 'your_email@example.com' msg['To'] = 'recipient@example.com' msg['Subject'] = '定时邮件' # 添加附件 with open('file.zip', 'rb') as f: part = MIMEBase('application', 'octet-stream') part.set_payload(f.read()) encoders.encode_base64(part) part.add_header('Content-Disposition', f'attachment; filename="file.zip"') msg.attach(part) # 发送邮件 with smtplib.SMTP_SSL('smtp.example.com', 465) as smtpObj: smtpObj.login('your_email@example.com', 'your_password') smtpObj.send_message(msg) # 清理文件和目录 os.remove('file.zip') directory = "LocationDir" location = "" path = os.path.join(location, directory) if os.path.exists(path): shutil.rmtree(path) def auto_email_sending(): # 选择一种调度方式,此处为每30秒执行一次 schedule.every(30).seconds.do(email_creation_sending) while True: schedule.run_pending() time.sleep(1) auto_email_sending()
5. 额外注意事项
- 避免过于频繁发送邮件,根据邮件服务商限制调整调度间隔;
- 添加异常捕获,防止单个任务失败导致整个调度器崩溃:
import socket def email_creation_sending(): try: # 原有逻辑 except socket.gaierror: print("DNS解析失败,稍后重试") time.sleep(5) except Exception as e: print(f"发送失败: {str(e)}")
内容的提问来源于stack exchange,提问作者THUnt
相关产品推荐
相关产品推荐

