在Python中将发件人的姓名添加到电子邮件的发件人字段

17

我正在尝试使用以下代码发送电子邮件。

import smtplib
from email.mime.text import MIMEText

sender = 'sender@sender.com'

def mail_me(cont, receiver):
    msg = MIMEText(cont, 'html')
    recipients = ",".join(receiver)
    msg['Subject'] = 'Test-email'
    msg['From'] = "XYZ ABC"
    msg['To'] = recipients
    # Send the message via our own SMTP server.
    try:
        s = smtplib.SMTP('localhost')
        s.sendmail(sender, receiver, msg.as_string())
        print "Successfully sent email"
    except SMTPException:
        print "Error: unable to send email"
    finally:
        s.quit()


cont = """\
   <html>
     <head></head>
     <body>
       <p>Hi!<br>
          How are you?<br>
          Here is the <a href="http://www.google.com">link</a> you wanted.
       </p>
     </body>
   </html>
   """
mail_me(cont,['xyz@xyzcom'])

我希望在收到电子邮件时,发件人的名称显示为“XYZ ABC”,并且其电子邮件地址为“sender@sender.com”,但是当我接收电子邮件时,在电子邮件信息的“发送者”字段中收到了奇怪的详细信息。
[![from:    XYZ@<machine-hostname-appearing-here>
reply-to:   XYZ@<machine-hostname-appearing-here>,
ABC@<machine-hostname-appearing-here>][1]][1]

我附上了一封我收到的电子邮件的截图。

我应该如何根据我的需求进行修复。


你成功配置了自己的SMTP服务器了吗? - Gahan
7个回答

43
这应该可以工作:
msg['From'] = "Your name <Your email>"

以下是一个示例:

import smtplib
from email.mime.text import MIMEText


def send_email(to=['example@example.com'],
               f_host='example.example.com',
               f_port=587,
               f_user='example@example.com',
               f_passwd='example-pass',
               subject='default subject',
               message='content message'):
    smtpserver = smtplib.SMTP(f_host, f_port)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(f_user, f_passwd)  # from email credential
    msg = MIMEText(message, 'html')
    msg['Subject'] = 'My custom Subject'
    msg['From'] = "Your name <Your email>"
    msg['To'] = ','.join(to)
    for t in to:
        smtpserver.sendmail(f_user, t, msg.as_string())  # you just need to add 
                                                         # this in for loop in 
                                                         # your code.
    smtpserver.close()
    print('Mail is sent successfully!!')

    cont = """
    <html>
    <head></head>
    <body>
    <p>Hi!<br>
      How are you?<br>
      Here is the <a href="http://www.google.com">link</a> you wanted.
    </p>
    </body>
    </html>
    """
    try:
        send_email(message=cont)
    except:
        print('Mail could not be sent')

1
欢迎来到 Stack Overflow!一般来说,最好提供一个带有解释和完整示例的答案。 - Arian Acosta
6
非常好!谢谢。但是我注意到一些电子邮件客户端(比如老版本的Outlook)会在收件箱中显示your@email.com为发件人。我认为正确的做法应该是导入 from email.header import Headerfrom email.utils import formataddr,然后执行以下操作:msg ['From'] = formataddr((str(Header('你的名字', 'utf-8')),'your@email.com')). - noamyg
1
只想添加新的情况。当我使用这样的文本“Company Name CO.,LTD <email>”时,它从未通过。但是当我写“(Company Name CO.,LTD) <email>”时,它会起作用。python 3.7 - user9032546
这里不需要for循环。根据官方文档,sendmail函数的第二个参数是RFC 822地址字符串列表(裸字符串将被视为具有1个地址的列表)。我们可以只使用smtpserver.sendmail(f_user, to, msg.as_string())来简化代码。 - luke77
@noamyg,我已经按照上面的方法尝试了你的策略,发件人姓名显示得很好,但是电子邮件地址总是显示为Gmail地址。your@email.com应该做什么? - fazistinho_
显示剩余3条评论

1

我刚刚在gmx.com上测试了以下代码,它可以正常工作。虽然你是否获得同样的结果还是个问题。
我已经用gmail替换了所有关于我的电子邮件服务的引用。

#!/usr/bin/python

#from smtplib import SMTP # Standard connection
from smtplib import SMTP_SSL as SMTP #SSL connection
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

sender = 'example@gmail.com'
receivers = ['example@gmail.com']


msg = MIMEMultipart()
msg['From'] = 'example@gmail.com'
msg['To'] = 'example@gmail.com'
msg['Subject'] = 'simple email via python test 1'
message = 'This is the body of the email line 1\nLine 2\nEnd'
msg.attach(MIMEText(message))

ServerConnect = False
try:
    smtp_server = SMTP('smtp.gmail.com','465')
    smtp_server.login('#name#@gmail.com', '#password#')
    ServerConnect = True
except SMTPHeloError as e:
    print "Server did not reply"
except SMTPAuthenticationError as e:
    print "Incorrect username/password combination"
except SMTPException as e:
    print "Authentication failed"

if ServerConnect == True:
    try:
        smtp_server.sendmail(sender, receivers, msg.as_string())
        print "Successfully sent email"
    except SMTPException as e:
        print "Error: unable to send email", e
    finally:
        smtp_server.close()

0

这应该可以解决问题:

mail_me(cont,['xyz@xyzcom']) 替换为

mail_me(cont,'xyz@xyz.com')

不行,那并没有解决问题。此外smtplib接受收件人电子邮件地址列表而非字符串,因此无法将其替换为字符串。 - cool77

0

空格不是电子邮件地址中的有效字符。特殊字符只允许在外部表示法中使用,该表示法应该用双引号括起来。此外,大多数SMTP服务器实际上使用标题重写来确保地址处于标准格式。由于您的地址包含空格,因此它被分割,并且由于未被引号括起来,服务器地址被追加到其后面。

您只需将msg['From'] = "XYZ ABC"替换为

msg['From'] = '"XYZ ABC"'

强制将地址包含在双引号中。


0
import smtplib
from email.mime.text import MIMEText

def send_email(to=['example@example.com'], f_host='example.example.com', f_port=587, f_user='example@example.com', f_passwd='example-pass', subject='default subject', message='content message'):
    smtpserver = smtplib.SMTP(f_host, f_port)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(f_user, f_passwd) # from email credential
    msg = MIMEText(message, 'html')
    msg['Subject'] = 'My custom Subject'
    msg['From'] = "Admin"
    msg['To'] = ','.join(to)
    for t in to:
        smtpserver.sendmail(f_user, t, msg.as_string())  # you just need to add this in for loop in your code.
        smtpserver.close()
    print('Mail is sent successfully!!')


cont = """\
   <html>
     <head></head>
     <body>
       <p>Hi!<br>
          How are you?<br>
          Here is the <a href="http://www.google.com">link</a> you wanted.
       </p>
     </body>
   </html>
   """
try:
    send_email(message=cont)
except:
    print('Mail could not be sent')

在上述方法中,我尝试发送邮件,这对我来说是有效的,我甚至能够将邮件发送到我的Gmail帐户(在垃圾邮件文件夹中)。 如果您遇到任何其他相关问题,请告诉我。


0

虽然上述方法是可以的,但更明确的方法是利用email.headerregistry中的Address

Address类有4个参数: (摘自文档)

display_name - 地址的显示名称部分(如果有),所有引号都已删除。如果地址没有显示名称,则此属性将为空字符串。

username - 地址的用户名部分,所有引号都已删除。

domain - 地址的域名部分。

addr_spec - 地址的用户名@域名部分,正确引用以用作裸地址(如上所示的第二种形式)。此属性不可变。

import smtplib
from email.message import EmailMessage
from email.headerregistry import Address

msg = EmailMessage()
msg.set_content('Hello Stackoverflow!')

msg['Subject'] = 'SO'
msg['From'] = Address(display_name="Name", addr_spec="info@mydomain.com")
msg['To'] = "receiver@domain.com"

# Send the message via our own SMTP server.
server = smtplib.SMTP_SSL('smpt.gmail.net', 465) # place your own host
server.login("info@mydomain.com", "mypassword")
server.send_message(msg)
server.quit()

0

是的。如果您看到代码,我在标题中使用了“From”。msg['From'] = "XYZ ABC" - cool77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接