PYTHON发邮件550(FROM HEADER IS MISSING OR INVAILD)

发布于 2023-12-19  283 次阅读


  • 先贴一个发送邮件的脚本
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
import sys
import time

#设置服务器,在腾讯邮箱设置中查看
mail_host="smtp.exmail.qq.com"  

#你的邮箱名
mail_user="email@drinkflower.asia"    

#你的qq密码
mail_pass=""   

#收件人显示的发件人
sender = 'email@drinkflower.asia'

# 接收邮件的邮箱名,要群发的话多个邮箱之间加上;
receivers = ['email@drinkflower.asia']  

#你要发的内容
txt=""

message = MIMEText(txt, 'plain', 'utf-8')

#邮件中显示的发件人,<>中的内容如果和上面的sender不一样,收件人收件会得到警告
message['From'] = Header("drinkflower<email@drinkflower.asia>", 'utf-8')

#收件人,没试过设置的和上面receivers不一样会怎么样
message['To'] =  Header("email@drinkflower.asia", 'utf-8')

#邮件标题
subject = '来自drinkflower的通知'

message['Subject'] = Header(subject, 'utf-8')

#465是stmp邮件服务器开放的端口,qq邮箱可以在设置中查看
smtpObj = smtplib.SMTP_SSL(mail_host, 465)   

smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
  • 有的时候写了message['From'],也会出现报错550,'The "From" header is missing or invalid,这是因为格式错了
根据RFC2047, RFC822协议,邮件标头中的'From'形式为:
1. 邮箱地址形式:prefix@domain, 如 'abc@qq.com'。
2. 昵称+空格+<邮箱地址>形式:nickname <prefix@domain>,其中,nickname为ASCII字符集中字符组合或编码文本:
(1)如果昵称全为ASCII字符,如'ABC',邮箱地址为'abc@qq.com',则标头中的'From'为'ABC <abc@qq.com>'。注
意'ABC'和'<abc@qq.com>'之间用空格隔开;
(2)如果昵称包含非ASCII字符,如中文,则请使用base64对昵称进行编码。nickname最终的形式为:"=?" charset "?" 
encoding "?" encoded-text "?="。其中,charset为字符集;encoding为编码方式,'B'代表base64;encoded-text为
编码后的文本。例如,昵称为'QQ邮箱昵称示例',邮箱地址为'abc@qq.com',则对昵称进行base64编码,字符集使用UTF-8,
则nickname为 '=?UTF-8?B?UVHpgq7nrrHmmLXnp7DnpLrkvos=?=',最终邮件标头中的'From'为'"=?utf-8?B?
UVHpgq7nrrHmmLXnp7DnpLrkvos=?=" <abc@qq.com>'。注意编码文本和邮件地址间用空格隔开。
  • 贴一个生成header的脚本,英文用上面的脚本,中文用下面的
import base64

def encode_name(name, charset='UTF-8'):
    encoded_name = base64.b64encode(name.encode(charset)).decode()
    return f'=?{charset}?B?{encoded_name}?='

def format_from_field(nickname, email):
    if all(ord(char) < 128 for char in nickname):  # 判断是否全为ASCII字符
        return f'{nickname} <{email}>'
    else:
        encoded_name = encode_name(nickname)
        return f'"{encoded_name}" <{email}>'

# 测试示例
nickname_ascii = 'ABC'
email_ascii = 'abc@example.com'
from_field_ascii = format_from_field(nickname_ascii, email_ascii)
print(from_field_ascii)

nickname_non_ascii = 'QQ邮箱昵称示例'
email_non_ascii = 'abc@example.com'
from_field_non_ascii = format_from_field(nickname_non_ascii, email_non_ascii)
print(from_field_non_ascii)
  • 最后贴一个flask的简单邮件api,对外开放的话还得消息队列,鉴权和轮询之类的
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
import random
import string
import time
import jwt
from flask import Flask,request,make_response
import logging
import requests
import pymysql
import configparser
from flask_cors import CORS
import openai
config = configparser.RawConfigParser()
config.read('config.ini', encoding='utf-8')

def send(rece,num):
    mail_host="smtp.exmail.qq.com"  
    mail_user="email@drinkflower.asia"    
    mail_pass=""   
    sender = 'email@drinkflower.asia'
    receivers = ['%s'%rece]  
    txt=""%num
    message = MIMEText(txt, 'plain', 'utf-8')
    message['From'] = Header("drinkflower.asia <email@drinkflower.asia>",)
    message['To'] =  Header("%s"%rece, 'utf-8')
    subject = ''
    message['Subject'] = Header(subject, 'utf-8')
    smtpObj = smtplib.SMTP_SSL(mail_host, 465)   
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
werkzeug_logger = logging.getLogger('werkzeug')
werkzeug_logger.setLevel(logging.ERROR)
@app.route('/', methods=["GET"])
def get():
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))+'   '+request.url)
    try:
        send(user,num)
        response = make_response("t")
        response.status_code = 200
        return response
    except:
        response = make_response("f")
        response.status_code = 200
        return response

app.run(debug=True, host='0.0.0.0', port=5000)
届ける言葉を今は育ててる
最后更新于 2024-03-09