You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:35:48