python SMTP邮件发送
程序员文章站
2022-04-15 17:05:37
本例使用的时python2.7环境,python3的操作应该也是差不多的。 需要用到smtplib和email两个包。 发送文本类型的邮件 下面看个发送文本邮件的例子(使用网易163的SMTP): 好像网易的SMTP有坑,message['From']和message['To']都要和sender和 ......
本例使用的时python2.7环境,python3的操作应该也是差不多的。
需要用到smtplib和email两个包。
发送文本类型的邮件
下面看个发送文本邮件的例子(使用网易163的smtp):
# -*- coding: utf-8 -*- import smtplib from email.mime.text import mimetext from email.header import header from email.utils import formataddr # 第三方smtp mail_host = "smtp.163.com" # smtp服务器 mail_user = "sender@163.com" # 发送者邮箱 mail_pass = "******" # 邮箱的客户端授权码 sender = "sender@163.com" # 邮件的发送者 recivers = ["bob@qq.com", "someone@gmail.com"] # 邮件接收者,可以指定多个 # 三个参数:第一个为文本内容,第二个设置文本格式,第三个设置字符编码 message = mimetext('python邮件发送测试', 'plain', 'utf-8') message['from'] = sender; # == message['from'] = formataddr(['sender', sender]) message['to'] = ", ".join(recivers) # == message['to] = formataddr(['ok', ', '.join(recivers)]) subject = 'python 邮件测试' message['subject'] = header(subject, 'utf-8') try: smtpobj = smtplib.smtp() smtpobj.connect(mali_host, 25) # 连接smtp,端口为25 smtpobj.set_debuglevel(1) smtpobj.login(mail_user, mail_pass) smtpobj.sendmail(sender, recivers,message.as_string()) print "emails send successfully" except smtplib.smtpexception: print "error:cannot send emails" smtpobj.quit() # 关闭连接
好像网易的smtp有坑,message['from']和message['to']都要和sender和recivers一致才可以,还有标题和内容尽量不要有敏感词,否则会被服务器判为垃圾邮件而发不出去,我第一次就因为subject带有“smtp”而被拦截(滑稽.gif)。
如果邮件发送失败,可以查看set_debuglevel()函数返回的状态码来判定什么原因。
发送html格式的邮件
与发送文本不同的地方就是将mimetext中的_subtype设为html,发送带图片的html还要创建mimemultipart()实例。
# -*- coding: utf-8 -*- import smtplib from email.header import header from email.mime.text import mimetext from email.mime.multipart import mimemultipart from email.mime.image import mimeimage # 第三方smtp mail_host = "smtp.163.com" # smtp服务器 mail_user = "sender@163.com" # 发送者邮箱 mail_pass = "******" # 邮箱的客户端授权码 sender = "sender@163.com" recivers = ["bob@qq.com", "alice@qq.com"] # 接收邮件 msg = mimemultipart('related') msg['from'] = sender msg['to'] = ", ".join(recivers) subject = 'html 1m4g3' msg['subject'] = header(subject, 'utf-8') mail_msg = """ <h1>html image测试</h1> <p><a href="http://www.baidu.com">learn more</a></p> <p><img src="cid:image1"></p> """ msgalternative = mimemultipart('alternative') msg.attach(msgalternative) msgalternative.attach(mimetext(mail_msg, 'html', 'utf-8')) # 指定当前目录的图片 fp = open('test1.gif', 'rb') msgimage = mimeimage(fp.read()) fp.close() # 定义图片id,在html中引用 msgimage.add_header('content-id', '<image1>') msg.attach(msgimage) try: smtpobj = smtplib.smtp() smtpobj.connect(mail_host, 25) # 25 smtp port smtpobj.set_debuglevel(1) smtpobj.login(mail_user, mail_pass) smtpobj.sendmail(sender, recivers, msg.as_string()) print "emails send sucessfully" except smtplib.smtpexception: print "error:cannot send emails" smtpobj.quit()
发送带附件的邮件
# -*- coding: utf-8 -*- import smtplib from email.header import header from email.mime.text import mimetext from email.mime.multipart import mimemultipart from email.mime.image import mimeimage # 第三方smtp mail_host = "smtp.163.com" # 设置服务器 mail_user = "sender@163.com" mail_pass = "******" sender = "sender@163.com" recivers = ["bob@qq.com", "alice@qq.com"] # 接收邮件 # 创建附件实例 msg = mimemultipart() msg['from'] = sender msg['to'] = ", ".join(recivers) subject = '邮件附件' msg['subject'] = header(subject, 'utf-8') # 邮件正文: mimetext('邮件正文如下', 'html', 'utf-8') # 构造附件,传送当前目录下的txt文件: att1 = mimetext(open('test1.txt', 'rb').read(), 'base64', 'utf-8') att1["content-type"] = 'application/octet-stream' # 这里的filename可以任意命名,成为邮件中显示的文件名 att1["content-disposition"] = 'attachment;filename="test_1.txt"' msg.attach(att1) try: smtpobj = smtplib.smtp() smtpobj.connect(mail_host, 25) # 25 smtp port smtpobj.set_debuglevel(1) smtpobj.login(mail_user, mail_pass) smtpobj.sendmail(sender, recivers, msg.as_string()) print "emails send sucessfully" except smtplib.smtpexception: print "error:cannot send emails" smtpobj.quit()
发送正常的就会返回250状态码:
发送失败返回的554:
总结
搞这些操作一是想弄明白智能合约ctf里怎么实现用邮箱发来flag的,再一个就是想补补编程(你打代码像蔡徐坤.gif)。
总之在里面遇到很多坑,而且大部分都是返回的554(可能被判为垃圾邮件而拦截掉了),这里的原因大概率是因为subject有些文字不符(像“test"这种都会被拦截)。还有在批量发送时,recivers是一个list,那么message['to']中需要用逗号和join()函数转成字符串。
over!