SMTP发送邮件

Posted 40块钱抓娃娃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SMTP发送邮件相关的知识,希望对你有一定的参考价值。

 

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、html邮件以及带附件的邮件。

Python对SMTP支持有smtplib和email两个模块:

  • email负责构造邮件,
  • smtplib负责发送邮件。

简单邮件发送

先来个简单的邮件来个入门:

  首先里用email模块来构建一个简单邮件文本:

form email.mime.text import MIMEText
msg = MIMEText(‘Hello,send by Python‘,‘plain‘,‘utf-8‘)

构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入‘plain‘表示纯文本,最终的MIME就是‘text/plain‘,最后一定要用utf-8编码保证多语言兼容性。
然后利用smtplib发送出去:

import smtplib
server = smtplib.SMTP(‘smtp.exmail.qq.com‘, 25) # SMTP协议默认端口是25    加密的端口为465
server.set_debuglevel(1)
server.login(‘[email protected]‘, ‘password‘)
server.sendmail(‘[email protected]‘, [‘[email protected]‘,], msg.as_string())  # 这里是自己给自己发邮件
server.quit()

我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应。login()方法用来登录SMTP服务器,sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文是一个stras_string()MIMEText对象变成str

完整的邮件发送

没有主题,没有发件人姓名,这......再试试,这里我们需要把想要的信息加入到MIMEText中才可以,来吧 。试试 , 这里我复制的是廖海峰的代码。

_format_addr()来格式化一个邮件地址。注意不能简单地传入name <[email protected]>,因为如果包含中文,需要通过Header对象进行编码。

msg[‘To‘]接收的是字符串而不是list,如果有多个邮件地址,用,分隔即可。

from email import encoders  # 这个不知道是干什么用的, 猜测是编码用的
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr

import smtplib

def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, ‘utf-8‘).encode(), addr))

from_addr = input(‘From: ‘)
password = input(‘Password: ‘)
to_addr = input(‘To: ‘)
smtp_server = input(‘SMTP server: ‘)

msg = MIMEText(‘hello, send by Python...‘, ‘plain‘, ‘utf-8‘)
msg[‘From‘] = _format_addr(‘Python爱好者 <%s>‘ % from_addr)
msg[‘To‘] = _format_addr(‘管理员 <%s>‘ % to_addr)
msg[‘Subject‘] = Header(‘来自SMTP的问候……‘, ‘utf-8‘).encode()

server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()

发送HTML邮件

在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:

msg = MIMEText(‘<html><body><h1>Hello</h1>‘ +
    ‘<p>send by <a href="http://www.python.org">Python</a>...</p>‘ +
    ‘</body></html>‘, ‘html‘, ‘utf-8‘)

发送带附件的邮件

带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可:

from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart,MIMEBase
from email.utils import parseaddr, formataddr
def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, ‘utf-8‘).encode(), addr))
msg = MIMEMultipart()
msg[‘From‘] = _format_addr(‘Python爱好者 <%s>‘ % ‘[email protected]‘)
msg[‘To‘] = _format_addr(‘管理员 <%s>‘ % ‘[email protected]‘)
msg[‘Subject‘] = Header(‘来自SMTP的问候……‘, ‘utf-8‘).encode()

# 邮件正文是MIMEText:
msg.attach(MIMEText(‘send with file...‘, ‘plain‘, ‘utf-8‘))

# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
with open(‘manage.py‘, ‘rb‘) as f:
    # 设置附件的MIME和文件名,这里是png类型:
    mime = MIMEBase(‘text‘, ‘py‘, filename=‘manage.py‘)
    # 加上必要的头信息:
    mime.add_header(‘Content-Disposition‘, ‘attachment‘, filename=‘manage.py‘)
    mime.add_header(‘Content-ID‘, ‘<0>‘)
    mime.add_header(‘X-Attachment-Id‘, ‘0‘)
    # 把附件的内容读进来:
    mime.set_payload(f.read())
    # 用Base64编码:
    encoders.encode_base64(mime)
    # 添加到MIMEMultipart:
    msg.attach(mime)

import smtplib
server = smtplib.SMTP(‘smtp.exmail.qq.com‘, 25) # SMTP协议默认端口是25    加密的端口为465
server.set_debuglevel(1)
server.login(‘[email protected]‘, ‘[email protected]‘)
server.sendmail(‘[email protected]‘, [‘[email protected]‘,], msg.as_string())
server.quit()

 

待续。。。

 

以上是关于SMTP发送邮件的主要内容,如果未能解决你的问题,请参考以下文章

接单日记SMTP发送邮件

Python邮件发送。为啥我用smtp发送邮件,发送成功没有报错,却没有收到邮件?求解

使用 localhost SMTP 发送邮件

通过 SMTP 发送邮件?

使用 smtp mandrill 发送电子邮件的问题

无法使用 PHP 代码和 SMTP 服务器向 yahoo(任何地址)发送邮件