求助:将Python变量传入独立HTML文件实现邮件发送时变量未生效
Got it, let's tackle this variable substitution issue for your HTML email. The core problem is that reading the raw index.html file directly won't automatically replace placeholders like first_header with your Python values—you need a template rendering mechanism to inject those variables dynamically. Here are two reliable approaches:
Approach 1: Use Jinja2 (Recommended for Scalable Projects)
Jinja2 is Python's go-to template engine, perfect for handling dynamic HTML content (including CSS styles) with clean variable injection.
Step 1: Install Jinja2
If you haven't already, install the package via pip:
pip install jinja2
Step 2: Organize Your Project Structure
Arrange your files like this to keep templates separate:
your_project/ ├── app.py └── templates/ └── index.html
Step 3: Update index.html with Jinja2 Placeholders
Modify your HTML template to use double curly braces for dynamic variables. For example:
<!DOCTYPE html> <html> <head> <style> .header { color: #2c3e50; font-size: 24px; font-weight: bold; } .content { margin-top: 16px; line-height: 1.6; } </style> </head> <body> <h1 class="header">{{ first_header }}</h1> <!-- Add rest of your styled HTML content here --> </body> </html>
Step 4: Modify mailer2 to Render the Template
Update your app.py to load the template and inject your variable:
from jinja2 import Environment, FileSystemLoader import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def mailer2(addr_from, addr_to, title, password): # Set up Jinja2 to load templates from the "templates" folder env = Environment(loader=FileSystemLoader('templates')) template = env.get_template('index.html') # Render the template with your variable (replace "hi" with dynamic values as needed) html_content = template.render(first_header="hi") # Build the email message msg = MIMEMultipart('alternative') msg['From'] = addr_from msg['To'] = addr_to msg['Subject'] = title # Attach the rendered HTML content msg.attach(MIMEText(html_content, 'html')) # Send the email (adjust SMTP settings for your provider, e.g., Gmail uses smtp.gmail.com:465) with smtplib.SMTP_SSL('smtp.your-provider.com', 465) as server: server.login(addr_from, password) server.sendmail(addr_from, addr_to, msg.as_string())
Approach 2: Simple String Replacement (Quick Fix for Basic Templates)
If you don't want to use a template engine, manual string replacement works for small, simple templates.
Step 1: Add a Custom Placeholder to index.html
Use a unique marker like [first_header] in your HTML:
<h1 class="header">[first_header]</h1>
Step 2: Update mailer2 to Replace the Placeholder
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def mailer2(addr_from, addr_to, title, password): # Read the raw HTML file with open('index.html', 'r') as f: html_raw = f.read() # Replace the placeholder with your Python variable html_content = html_raw.replace('[first_header]', 'hi') # Build and send the email (same as Approach 1) msg = MIMEMultipart('alternative') msg['From'] = addr_from msg['To'] = addr_to msg['Subject'] = title msg.attach(MIMEText(html_content, 'html')) with smtplib.SMTP_SSL('smtp.your-provider.com', 465) as server: server.login(addr_from, password) server.sendmail(addr_from, addr_to, msg.as_string())
Critical Note for Email CSS
Many email clients (like Gmail) don't support <style> tags in the <head> section fully. For maximum compatibility, inline your CSS styles (e.g., <h1 style="color: #2c3e50; font-size: 24px;">{{ first_header }}</h1>). If your template is complex, tools like Premailer can automate this inline conversion.
内容的提问来源于stack exchange,提问作者user3558939

