利用python发送邮件技术解析

利用python发送邮件

  • 利用python3发送邮件时候,首先需要了解SMTP:SMTP(Simple Mail Transfer
    Protocol)简单邮件传输协议,是在internet传输email的事实标准。它是一个相对简单的基于文本的协议,在其之上指定了一条消息的一个或多个接受者(在大多数情况下被确认是存在的),然后消息文本会被传输。SMTP用于在邮件服务器之间发送电子邮件和路由电子邮件。
  • 简单来说SMTP就是发送邮件的协议,python内置对SMTP的支持,python提供的smtplib模块定义了一个SMTP客户端会话对象,可以用它来实现python收发邮件。
  • python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib模块负责发送邮件

(1)smtplib模块

import smtplib
smtp=smtplib.SMTP()
smtp.connect('smtp.163.com,25')
smtp.login(username,password)
smtp.sendmail(sender,receiver,msg.as_string())
smtp.quit()

简单说明:

  • smtplib.SMTP():实例化SMTP()

  • connect(host,port)

  • host - 代表运行SMTP服务器的主机,可以指定主机的IP地址或者域名,属于可选参数,常用的邮箱域名有:新浪邮箱:smtp.sina.com
    新浪VIP:smtp.vip.sina.com 、搜狐邮箱:smtp.sohu.com、126邮箱:smtp.126.com
    139邮箱:smtp.139.com、163网易邮箱:smtp.163.com、qq邮箱:smtp.qq.com

  • port- 如果提供主机参数,需要指定SMTP服务器正在监听的端口,通常这个端口为25,qq邮箱的为465
    local_hostname- 如果SMTP服务器在本地计算机上运行,那么可以只指定localhost选项。

  • username- 邮箱账号

  • password- 授权码,即客户端密码,不是邮箱登录密码,而是你在邮箱里边开通SMTP服务的时候设置的授权码。

  • sendmail(from_addr,to_addr,msg,…)

  • from_addr:邮件发送者地址

  • to_addr:邮件接受者地址,(也可以是多个接受者,此时只需要将多个接受者放在一个列表里即可,eg[‘接受者地址1’,‘接受者地址2’],
    多个接受者之间用逗号连接)

  • msg:邮件内容,一般是msg.as_string():其中as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str

  • quit():用于结束SMTP会话

(2)email模块

  • email模块下有mime包,mime英文全称为"Multipurpose Internet Mail
    Extensions",即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。

  • mime包下常用的有三个模块:text,image,multpart

  • 导入方法如下:

    from email.mime.image import MIMEImage
     from email.mime.multipart import MIMEMultipart
     from email.mime.text import MIMEText
    
  • 构造一个邮件对象就是一个message对象,如果构造一个MIMEText对象,就表示一个文本邮件对象;如果构造一个MIMEImage对象,就表示一个作为附件的图片;要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象,他们的继承关系如下:

     Message
     +- MIMEBase
        +- MIMEMultipart
        +- MIMENonMultipart
           +- MIMEMessage
           +- MIMEText
           +- MIMEImage
    

2.1 text说明

  • 邮件发送程序为了防止有些邮件阅读软件不能显示处理HTML格式的数据,通常都会用两种类型分别为:“text/plain"和"text/html”(普通纯文本选择plain,超文本HTML选择html),构造MIMEText对象时,第一个参数是邮件正文,第二个是MIME的subtype,最后一定要用utf-8编码来保证多语言兼容性。

2.2 Image说明

  • 要把图片嵌入到邮件正文中怎么做?直接在HTML邮件中链接图片地址不可行,因为大部分邮件服务商都会自动屏蔽带有外链的图片,因为不知道这些链接是否指向恶意网站。

  • 要把图片嵌入到网址中,我们只需要按照发送附件的方式,先把邮件作为附件添加进去,然后再HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。

     msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
             '<p><img src="cid:0"></p>' +
             '</body></html>', 'html', 'utf-8'))
    
  • 单纯添加图片如下:

    sendimagefile=open(r’D:\pythontest\testimage.png’,‘rb’).read()
    image = MIMEImage(sendimagefile)
    image.add_header(‘Content-ID’,’’)

2.3 multpart说明

  • 常见的multpart类型有三种:multpart/alternative、multpart/related/、multpart/mixed

  • 邮件类型为"multipart/alternative"的邮件包括纯文本正文(text/plain)和超文本正文(text/html)

  • 邮件类型为"multipart/related"的邮件正文中包括图片,声音等内嵌资源

  • 邮件类型为"multipart/mixed"的邮件包含附件。向上兼容,如果一个邮件有纯文本正文,超文本正文,内嵌资源,附件,则选择mixed类型。

  • 我们必须把Subject,From,To,Date添加到MIMEText对象或者MIMEMultipart对象中,邮件中才会显示主题,发件人,收件人,时间(若无时间,就默认一般为当前时间,该值一般不设置)

  • 如果我们发送HTML邮件,收件人通过浏览器或者Outlook之类的软件是可以正常浏览邮件内容的,但是,如果收件人使用的设备太古老,无法查看HTML邮件怎么办?解决方法是在发送HTML的同时再附加一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降为查看纯文本邮件。利用MIMEMultipart就可以组合一个HTML和plain,要注意指定subtype是alternative

2.4 加密SMTP

  1. 使用标准的25端口链接SMTP服务器时,使用的是明文传输,发送邮件的整个过程可能会被监听,要更安全地发送邮件,可以加密SMTP会话,实际上就是先创建SSL安全连接,然后再使用SMTP协议发送邮件

  2. 某些邮件服务商,例如Gmail,提供的SMTP服务必须要加密传输,(Gmail的SMTP端口号是587)如下:

    smtp_server = ‘smtp.gmail.com
    smtp_port = 587
    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    #剩下的代码和前面的一模一样:
    server.set_debuglevel(1)

  3. 只要在创建SMTP对象后,立刻调用starttls()方法,就创建了安全连接,后面的代码和其余的发送邮件的代码一样。

代码示例

1、简单的发送邮件

import smtplib
from email.mime.text import MIMEText
  
mail_host="smtp.163.com"
mail_user="你的邮箱账号"
mail_pass="邮箱登录授权码"

sender="发送者邮箱"
receivers=["收件人邮箱"]

content="python测试发送邮件2333"
title="测试邮件"
message=MIMEText(content,"plain","utf-8")
message["From"]="{}".format(sender)
message["To"]=",".join(receivers)
message["Subject"]=title

try:
    smtpObj=smtplib.SMTP_SSL(mail_host,465)
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender,receivers,message.as_string())
    print("发送成功")
except smtplib.SMTPException as e:
    print(e)

2、发送带附件的邮件

   import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

mail_host="smtp.163.com"
mail_user="你的邮箱账号"
mail_pass="你的邮箱登录授权码"

sender="发送者邮箱账号"
receivers=["收件人邮箱账号"]#可以是一个列表

#创建一个带附件的实例
content="邮件正文,用于测试带附件的邮件发送"
title="测试邮件"
message=MIMEMultipart()
message.attach(MIMEText(content,"plain","utf-8"))
message["From"]="{}".format(sender)
message["To"]=",".join(receivers)
message["Subject"]=title


#构造附件一,传送一个txt文件
att1=MIMEText(open("F:/pachong/b/aaa.txt","rb").read(),"base64","UTF-8")
att1["Content-Type"]="application/octet-stream"
att1["Content-Disposition"]='attachment;filename="aaa.txt"'
message.attach(att1)

#构造附件二,传送一个word文件
att2=MIMEText(open("F:/pachong/b/bbb.docx","rb").read(),"base64","UTF-8")
att2["Content-Type"]="application/octet-stream"
att2["Content-Disposition"]='attachment;filename="bbb.docx"'
message.attach(att2)

try:
    smtpObj=smtplib.SMTP_SSL(mail_host,465)
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender,receivers,message.as_string())
    print("发送成功")
except smtplib.SMTPException as e:
    print(e)

3、发送HTML格式邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL

from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

mail_host='smtp.163.com'
mail_user="你的邮箱账号"
mail_pass="邮箱授权码"

sender="你的邮箱账号"
receivers=["收件人1","收件人2"]

mail_content='邮件正文内容:HTML中添加图片'
mail_title='我是邮件标题'

msg=MIMEMultipart('related')
msg['Subject']=Header(mail_title,'utf-8')
msg['From']=sender
msg['To']=Header("接收测试者",'utf-8')  #接收者的别名

msgAlternative=MIMEMultipart("alternative")
msg.attach(msgAlternative)

mail_body="""

<p>你好,这是一份测试python自动发送邮件的邮件</p>
<p>这个邮件是HTML中添加图片的测试邮件</p>
<p><a href='www.baidu.com'>百度首页</a></p>
<p>图片演示:</p>
<p>img src="cid:send_image")</p>
<OK,演示结束></p>

"""

msgText=(MIMEText(mail_body,'html','utf-8'))
msgAlternative.attach(msgText)

#指定图片地址
fp=open('F:/pachong/b/kd.jpg','rb')
msgImage=MIMEImage(fp.read())
fp.close()

#定义图片 ID在 HTML 文本中引用
msgImage.add_header('Content-ID','<send_image>')
msg.attach(msgImage)

#SSL登录
try:
    smtpObj=smtplib.SMTP_SSL(mail_host,465)
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender,receivers,msg.as_string())
    smtpObj.quit()
    print("发送成功")
except smtp

猜你喜欢

转载自blog.csdn.net/hsy_okc/article/details/84999581