发送计算机需要找到某一台中间主机,接着这台中间主机需要找到离接受主机更近的一些主机,所以在发送主机和接受主机之间会有多台被称为跳板的主机。每一个电子邮件消息头标题,就会记录它在被接受之前经过了哪里。
消息传输代理(MTA)
这是在邮件交换主机上运行的服务器进程,它负责邮件的路由、队列处理和发送工作。MTA就是发送端与最终接受端之间的跳板主机,也称为消息传输的代理。
MTA负责两件事:
——如何找到消息应该到达的下一台MTA(由DNS来查找目的域名的MX来完成)
——如何与另一台MTA进行通信;
MTA之间的通信协议
为了发送电子邮件,邮件客户端必须连接到一个MTA,MTA之间通过消息传输系统互相通信,只有两个MTA都是用这个协议时才能进行通信。
SMTP
SMTP时两个MTA主机之间通信的一种协议,它需要一个邮件队列,但这需要额外的存储和管理工作。用SMTP把一个邮件消息从一台MTA发送给另一台MTA,发送时必须连接到一个外部STMP服务器,此时邮件程序是一个SMTP客户端,而SMTP服务器也称为消息的第一站。
LMTP
LMTP提供了更轻量级的系统,以除了对邮件队列的需求,但邮件需要立即发送,LMTP服务器不暴露到外面直接与连接到因特网的邮件网关工作,以表示接受或拒绝一个消息,网关作为LMTP的邮件队列。
POP(邮局协议)
第一个用于下载邮件的协议,目的是让用户在工作站可以访问邮箱服务器里的邮件
IMAP
比POP拥有更完整的解决方案,POP无法很好地应对多邮件客户端,而IMAP则可以通过不同的设备使用电子邮件。
基本流程:
1.用163和qq邮箱来实现
登陆163邮箱网页版,在设置里开启POP3/SMTP/IMAP服务,用手机短信认证设置授权码
2.python实现
smtpServer='smtp.163.com' #使用的服务器
sender='[email protected]' #发送端的邮箱地址
passwd='we***23' #授权码
receiver='148***[email protected]' #接受端的邮箱地址
subject='python20180304' #发送的主题
#发送的内容
content="""
hello python
"""
import smtplib
from email.mime.text import MIMEText #生成内容正确格式的模块
from mailConf import * #配置文件
def mail_content(): #生成发送内容的函数
msg=MIMEText(content,'plain','utf-8')
msg['From']=sender
msg['To']=receiver
msg['Subject']=subject
return msg
def sendMail():
try:
smtpObj=smtplib.SMTP(smtpServer) #生成一个对象,传入使用的服务器
smtpObj.login(sender,passwd) #登陆邮箱,邮箱地址和授权码
msg=mail_content() #发送内容的对象
smtpObj.sendmail(sender,receiver,msg.as_string())
except smtplib.SMTPException as e:
print("Error:send email failure:",e)
else:
print("send email success")
if __name__=='__main__':
sendMail()
smtpServer='smtp.163.com'
sender='[email protected]'
passwd='westos123'
receiver='[email protected]'
subject='hello_HTML'
with open('main_html.html') as f:
content=f.read()
import smtplib
from email.mime.text import MIMEText
from mailConf import *
def mail_content():
# 是一个MIMETEXT对象, 如果发送的是普通的文本文件, 则添加
msg = MIMEText(content, 'html', 'utf-8')
msg['From'] = sender
# 如果要给多个用户发送邮件, 需要将列表连接成字符串;
msg['To'] = "".join(receiver)
msg['Subject'] = subject
return msg
def sendMail():
try:
# 1. 连接smtp服务器;
smtpObj = smtplib.SMTP(smtpServer)
# 2. 登陆账户
smtpObj.login(sender, passwd)
# 生成合法格式的内容, 否则发送失败;
msg = mail_content()
# 3. 发送邮件
smtpObj.sendmail(sender, receiver, msg.as_string())
except smtplib.SMTPException as e:
print("Error:邮件发送失败,",e)
else:
print("邮件发送%s成功" %(receiver))
if __name__ == "__main__":
sendMail()
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from mailConf import *
def read_file(filename):
"""读取附件文件的内容"""
with open(filename, 'rb') as f:
c_str = f.read()
return c_str
def mail_content():
# 创佳一个 MIMEMultipart对象, 可以添加很多内容, 比如附件
# **************此处修改MIMEMultipart()实例可以添加附件**************
msg = MIMEMultipart()
msg['From'] = sender
# 如果要给多个用户发送邮件, 需要将列表连接成字符串;
msg['To'] = "".join(receiver)
msg['Subject'] = subject
# 添加邮件正文
msg.attach(MIMEText("这是一个有附件的邮件正文."))
# 构造邮件的附件
att1_content = read_file('/etc/passwd')
# 构建附件1:
# Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,
# Base64就是一种基于64个可打印字符来表示二进制数据的方法。
att1 = MIMEText(att1_content, 'base64', 'utf-8')
# Content-Type,内容类型,一般是指网页中存在的Content-Type,
# 用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,
# 这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。
# 'application/octet-stream': .* ( 二进制流,不知道下载文件类型)
att1['Content-type'] = 'application/octet-stream'
# HTTP应答中,Content-Disposition 消息头指示回复的内容该以何种形式展示,
# 是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地
#
# inline(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),
# attachment(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,
# 将filename的值预填为下载后的文件
msg.attach(att1)
return msg
def sendMail():
try:
# 1. 连接smtp服务器;
smtpObj = smtplib.SMTP(smtpServer)
# 2. 登陆账户
smtpObj.login(sender, passwd)
# 生成合法格式的内容, 否则发送失败;
msg = mail_content()
# 3. 发送邮件
smtpObj.sendmail(sender, receiver, msg.as_string())
except smtplib.SMTPException as e:
print("Error:邮件发送失败,", e)
else:
print("邮件发送%s成功" % (receiver))
if __name__ == "__main__":
sendMail()
import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from mailConf import *
def read_file(filename):
"""读取附件文件的内容"""
with open(filename, 'rb') as f:
c_str = f.read()
return c_str
def mail_content():
# 创佳一个 MIMEMultipart对象, 可以添加很多内容, 比如附件
# **************此处修改MIMEMultipart()实例可以添加附件**************
# multipart/related类型除了可以携带各种附件外,
# 还可以将其它内容以内嵌资源的方式存储在邮件中。
# 比如我们在发送html格式的邮件内容时,可能使用图像作为html的背景;
msg = MIMEMultipart()
msg['From'] = sender
# 如果要给多个用户发送邮件, 需要将列表连接成字符串;
msg['To'] = "".join(receiver)
msg['Subject'] = subject
# multipart / alternative类型
# 如果邮件中同时存在纯文本和超文本内容,则邮件需要在Content - Type
# 域中定义multipart / alternative类型,
# 邮件通过其boundary中的分段标识将纯文本、超文本和邮件的其它内容分成不同的段。
msgAlter = MIMEMultipart()
msg.attach( msgAlter)
mail_msg = """
hello
#如果图片不能显示就显示"上海鲜花港 - 郁金香"
"""
msgAlter.attach(MIMEText(mail_msg, 'html', 'utf-8'))
with open('img/img01.jpg', 'rb') as f:
msg_image = MIMEImage(f.read())
msg_image.add_header('Content-ID','' )
msgAlter.attach(msg_image)
return msg
def sendMail():
try:
# 1. 连接smtp服务器;
smtpObj = smtplib.SMTP(smtpServer)
# 2. 登陆账户
smtpObj.login(sender, passwd)
# 生成合法格式的内容, 否则发送失败;
msg = mail_content()
# 3. 发送邮件
smtpObj.sendmail(sender, sender, msg.as_string())
except smtplib.SMTPException as e:
print("Error:邮件发送失败,", e)
else:
print("邮件发送%s成功" % (receiver))
if __name__ == "__main__":
sendMail()
设计思路:在系统中设置定时任务执行脚本,每天早上8:00从天气网中得到需要的天气数据,在经过处理,如果是雨天或雪天就自动发送电子邮件提醒带伞。
def readUrl(url):
# 生成字典, 指定用户代理为火狐浏览器, 而不是python脚本;
headers = {'User-Agent': 'Firefox/23.0'}
# 向url地址发起请求, 返回一个Request对象;
req = request.Request(url, headers=headers)
# 返回一个urlOpen对象, 该对象中包含访问的所有结果, 比如: 网页内容, 网页的状态码(200, 404)
urlObj = urlopen(req)
# 将读取的内容以utf-8编码显示;(中文显示不乱码)
urlContent = urlObj.read().decode('utf-8')
return urlContent
def sendMail():
try:
# 1. 连接smtp服务器;
smtpObj = smtplib.SMTP(smtpServer)
# 2. 登陆账户
smtpObj.login(sender, passwd)
# 生成合法格式的内容, 否则发送失败;
msg = mail_content()
# 3. 发送邮件
smtpObj.sendmail(sender, receiver, msg.as_string())
except smtplib.SMTPException as e:
print("Error:邮件发送失败,",e)
else:
print("邮件发送%s成功" %(receiver))
def main():
url = "http://www.weather.com.cn/data/cityinfo/101110101.html"
info = readUrl(url)
d = json.loads(info)
weather = d['weatherinfo']['weather']
if '雨' in weather or '雪' in weather:
sendMail()
if __name__=="__main__":
main()
在系统中设置定时任务
[kiosk@foundation77 Desktop]$ vim /etc/cron.d/filename