如何用Python的SMTP Lib发送带Gmail签名的邮件?
Python批量邮件发送程序自动添加Gmail签名的解决方案
问题说明
Python批量邮件发送程序运行正常,但通过smtplib发送的邮件未包含Gmail账号的默认签名。因程序需适配不同Gmail账号,无法硬编码签名,需通用实现方法。
程序代码
# Imports import pandas as pd import smtplib from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import sys import os import time from rich.progress import track import keyboard import tkinter as tk from tkinter import filedialog from os import system from colored import fg, attr # User Input Process sender_address = str(input("Please enter your email address!: ")) automail_art() sender_pass = str(input( "Please enter your Google App Email password (No data is stored anywhere!): ")) automail_art() user_sub = input("What would you like the subject line to say?: ") automail_art() user_greeting = input( "What would you like the greeting to be? (Hello, Greetings, etc.) [No symbols or names! JUST ONE WORD!]: ") automail_art() root = tk.Tk() root.withdraw() input(f"{fg('green_4')}Please choose the Excel File you would like to use for name and email address data. \nAfter selecting file click back into the terminal window. Press ENTER to continue\n\n") # This prompts user to input the file path of their CSV file. file_path = filedialog.askopenfilename() automail_art() input(f"{fg('yellow')}Please choose the Text File you would like to use for the body of your email. \nAfter selecting file click back into the terminal window. Press ENTER to continue\n\n") # This prompts user to input the file path of their Text file. txt_doc_path = filedialog.askopenfilename() automail_art() # PDF Process input("Please choose the PDF File you would like to attach to your email. \nAfter selecting file click back into the terminal window. Press ENTER to continue\n\n") pdf_path = filedialog.askopenfilename() automail_art() pdf_name = input( "What would you like to name the PDF file? (Do not inclue .pdf): ") automail_art() # Amount of emails the user wishes to send amount = int(input("How many emails would you like to send? ")) automail_art() txt_doc = open(txt_doc_path, "r") txt_doc_contents = txt_doc.read() # DataFrame Variable # Variable made for DataFrame to save time and make it more simple df = pd.read_excel(file_path, usecols=['First', 'MainEmail']) # Email sending process print("\n") # Amount is how many emails the user wants to send out. "cell_value" is which cell from the spreadsheet it is pulling data from. for cell_value in track(range(amount), description=f"{fg('green_1')}Sending Emails :) "): # "name_cell" is the cell that contains the first name of the recipient name_cell = df["First"].values[cell_value] # "email_cell" is the cell that contains the email address of the recipient email_cell = df["MainEmail"].values[cell_value] receiver_address = email_cell email_subj = user_sub # This variable contains the subject line # This is the intro sentence of the email being sent email_intro = user_greeting + " " + name_cell + "," message = MIMEMultipart() # Variable made to save time and make it more simple # Variable made to save time and make it more simple session = smtplib.SMTP('smtp.gmail.com', 587) session.starttls() # enable security # Login with email and password (The User's) session.login(sender_address, sender_pass) message['From'] = sender_address # From user's email address message['To'] = receiver_address # To recipient email address # The variable that contains the desired subject line message['Subject'] = email_subj message.attach(MIMEText(email_intro + txt_doc_contents, 'plain')) with open(pdf_path, "rb") as f: attach = MIMEApplication(f.read(), _subtype="pdf") attach.add_header('Content-Disposition', 'attachment', filename=str(pdf_name)) message.attach(attach) text = message.as_string() session.sendmail(sender_address, receiver_address, text) # This sends the email input("Emails have been sent successfully! Press any key to close the program!") # The End :)
可行解决方案
方案1:使用Gmail API发送邮件(推荐)
Gmail API会自动将账号设置中的签名添加到发送的邮件末尾,无需手动处理签名内容,天然适配所有Gmail账号。实现步骤:
- 前往Google Cloud Console启用Gmail API,创建OAuth 2.0客户端凭据(选择桌面应用类型)
- 安装依赖库:
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib - 替换原代码中
smtplib相关的发送逻辑,改用Gmail API调用,核心代码示例:
from googleapiclient.discovery import build from google.oauth2.credentials import Credentials from google.auth.transport.requests import Request from google_auth_oauthlib.flow import InstalledAppFlow import base64 from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication # 权限范围 SCOPES = ['https://www.googleapis.com/auth/gmail.send'] def get_gmail_service(): creds = None # 加载已保存的凭据 if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # 刷新或重新获取凭据 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( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 保存凭据供下次使用 with open('token.json', 'w') as token: token.write(creds.to_json()) return build('gmail', 'v1', credentials=creds) def send_email_with_attachment(service, sender, to, subject, message_text, pdf_path, pdf_name): # 构建带附件的邮件 message = MIMEMultipart() message['to'] = to message['from'] = sender message['subject'] = subject message.attach(MIMEText(message_text, 'plain')) # 添加PDF附件 with open(pdf_path, "rb") as f: attach = MIMEApplication(f.read(), _subtype="pdf") attach.add_header('Content-Disposition', 'attachment', filename=f"{pdf_name}.pdf") message.attach(attach) # 编码为Gmail API要求的格式 raw = base64.urlsafe_b64encode(message.as_bytes()).decode() body = {'raw': raw} service.users().messages().send(userId='me', body=body).execute() # 在循环中调用示例 service = get_gmail_service() send_email_with_attachment(service, sender_address, receiver_address, email_subj, email_intro + txt_doc_contents, pdf_path, pdf_name)
方案2:通过IMAP获取Gmail签名并插入邮件
若不想改用API,可通过IMAP协议读取Gmail账号的签名设置,手动追加到邮件正文:
- 开启Gmail账号的IMAP访问权限(在Gmail设置中开启)
- 通过IMAP登录后,查询
[Gmail]/Settings文件夹下的签名邮件,解析提取签名内容 - 将签名文本/HTML追加到邮件正文末尾
- 注意:此方法依赖Gmail的内部存储格式,可能因平台更新失效,稳定性不如API方案
内容的提问来源于stack exchange,提问作者gcb140
相关产品推荐
相关产品推荐

