笔记,邮件(1)
用Python实现邮件编写、发送整个流程。因为Python的强大,整个过程并不复杂。还是要小心,不然有各种错误。
假设我们自己的电子邮件地址是me@163.com,对方的电子邮件地址是friend@sina.com(注意地址都是虚构的哈),现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email地址,点“发送”,电子邮件就发出去了。这些电子邮件软件被称为MUA:Mail User Agent——邮件用户代理。
Email从MUA发出去,不是直接到达对方电脑,而是发到MTA:Mail Transfer Agent——邮件传输代理,就是那些Email服务提供商,比如网易、新浪等等。由于我们自己的电子邮件是163.com,所以,Email首先被投递到网易提供的MTA,再由网易的MTA发到对方服务商,也就是新浪的MTA。这个过程中间可能还会经过别的MTA,但是我们不关心具体路线,我们只关心速度。
Email到达新浪的MTA后,由于对方使用的是@sina.com的邮箱,因此,新浪的MTA会把Email投递到邮件的最终目的地MDA:Mail Delivery Agent——邮件投递代理。Email到达MDA后,就静静地躺在新浪的某个服务器上,存放在某个文件或特殊的数据库里,我们将这个长期保存邮件的地方称之为电子邮箱。
同普通邮件类似,Email不会直接到达对方的电脑,因为对方电脑不一定开机,开机也不一定联网。对方要取到邮件,必须通过MUA从MDA上把邮件取到自己的电脑上。
所以,一封电子邮件的旅程就是:
发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人
有了上述基本概念,要编写程序来发送和接收邮件,本质上就是:
-
编写MUA把邮件发到MTA;
-
编写MUA从MDA上收邮件。
发邮件时,MUA和MTA使用的协议就是SMTP:Simple Mail Transfer Protocol,后面的MTA到另一个MTA也是用SMTP协议。
收邮件时,MUA和MDA使用的协议有两种:POP:Post Office Protocol,目前版本是3,俗称POP3;IMAP:Internet Message Access Protocol,目前版本是4,优点是不但能取邮件,还可以直接操作MDA上存储的邮件,比如从收件箱移到垃圾箱,等等。
邮件客户端软件在发邮件时,会让你先配置SMTP服务器,也就是你要发到哪个MTA上。假设你正在使用163的邮箱,你就不能直接发到新浪的MTA上,因为它只服务新浪的用户,所以,你得填163提供的SMTP服务器地址:smtp.163.com,为了证明你是163的用户,SMTP服务器还要求你填写邮箱地址和邮箱口令,这样,MUA才能正常地把Email通过SMTP协议发送到MTA。
类似的,从MDA收邮件时,MDA服务器也要求验证你的邮箱口令,确保不会有人冒充你收取你的邮件,所以,Outlook之类的邮件客户端会要求你填写POP3或IMAP服务器地址、邮箱地址和口令,这样,MUA才能顺利地通过POP或IMAP协议从MDA取到邮件。
特别注意,目前大多数邮件服务商都需要手动打开SMTP发信和POP收信的功能,否则只允许在网页登录,如下:

#coding: utf-8
#SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。 import smtplib #负责发送邮件 from email.mime.text import MIMEText #构造邮件体 from email.header import Header #构造邮件头, 注意文件名不能去email等敏感词,不然会显示没有此模块 sender = '***@126.com' receiver = 'xxx@qq.com' smtpserver = 'smtp.126.com' username = '***@126.com' password = '????' #注意该密码非邮箱登录密码,是你自己设置的客户端授权密码 subject = '放假通知' content = """ one two three 大王叫我! """ # 以上是邮件的内容,以纯文本方式发送 msg = MIMEText(content, 'plain', 'utf-8') #第一个参数就是邮件正文,第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,最后一定要用utf-8编码保证多语言兼容性。 msg['Subject'] = Header(subject, 'utf-8') # 邮件的标题 msg['From'] = '***@126.com' # 发送端地址,注意要写准确,以官方显示的为准(大名非小名) msg['To'] = "xxx@qq.com" #这两行一定要写,确保信封发件人和信头发件人匹配,不然报错 smtp = smtplib.SMTP() # SMTP开通说明,详见http://www.cnblogs.com/testyao/p/6044410.html smtp.connect('smtp.126.com') # 使用connect方法链接到126邮箱,一般端口是25,省略不写 smtp.login(username, password) #用来登录SMTP服务器
smtp.set_debuglevel(1) #可以打印出和SMTP服务器交互的所有信息 for i in range(10): #重复发送十次。整个过程都以代码方式实现,想想还能进行其他好玩的操作 smtp.sendmail(sender, receiver, msg.as_string()) # 这句话才是邮件发送,括号内的顺序是:发送端,接收端,文件内容。由于可以一次发给多个人,所以传入一个list,邮件正文是一个str,as_string()把MIMEText对象变成str。 smtp.quit() # 断开smtp链接
结果:

关于邮件应用的一个简单例子
#邮件的应用其实就是借花献佛的策略,from和to不变,爬取的内容作为邮件的内容 import smtplib from email.mime.text import MIMEText from bs4 import BeautifulSoup from urllib.request import urlopen import time def sendMail(subject, body): msg = MIMEText(body) msg['Subject'] = subject msg['From'] = "***@126.com" msg['To'] = "xxx@qq.com" s = smtplib.SMTP() # SMTP开通说明,详见http://www.cnblogs.com/testyao/p/6044410.html s.connect('smtp.126.com') # 使用connect方法链接到126邮箱,一般端口是25,省略不写 s.login('***@126.com', '###') s.set_debuglevel(1) s.sendmail("***@126.com", "xxx@qq.com", msg.as_string()) s.quit() bsObj = BeautifulSoup(urlopen("https://isitchristmas.com/"), "html.parser") aa = (bsObj.find('noscript')) #通过网页代码定位选择的信息位置和格式 print(aa) print(aa.get_text()) #输出纯文本内容,也是我想要的东西 #if (bsObj.find("a", {"id":"answer"}).attrs['title'] != "不是"): if (bsObj.find('noscript').get_text() == "不是"): #这里用if..else...进行一次判断,如下所示可以进行封装无限循环... print("It is not Christmas yet.") else: sendMail("It's Christmas!", "According to http://itischristmas.com, it is Christmas!") ''' 例子提供的是每小时检查一次 https://isitchristmas.com/ 网站(根据日期判断当天是不是圣诞节),所以用while无限循环 bsObj = BeautifulSoup(urlopen("https://isitchristmas.com/")) while(bsObj.find("a", {"id":"answer"}).attrs['title'] == "NO"):#网站发生变更,所以对应的属性、内容发生改变 print("It is not Christmas yet.") time.sleep(3600) bsObj = BeautifulSoup(urlopen("https://isitchristmas.com/")) sendMail("It's Christmas!", "According to http://itischristmas.com, it is Christmas!") '''
结果:


下面是关于邮件较全面的模板,来自:http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343463.html
#####文件形式的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msg = MIMEText('你好','text','utf-8')#中文需参数‘utf-8’,单字节字符不需要 msg['Subject'] = Header(subject, 'utf-8') smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()
####HTML形式的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msg = MIMEText('<html><h1>你好</h1></html>','html','utf-8') msg['Subject'] = subject smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()
####带图片的HTML邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msgRoot = MIMEMultipart('related') msgRoot['Subject'] = 'test message' msgText = MIMEText('<b>Some <i>HTML</i> text</b> and an image.<br><img src="cid:image1"><br>good!','html','utf-8') msgRoot.attach(msgText) fp = open('h:\\python\\1.jpg', 'rb') msgImage = MIMEImage(fp.read()) fp.close() msgImage.add_header('Content-ID', '<image1>') msgRoot.attach(msgImage) smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msgRoot.as_string()) smtp.quit()
####带附件的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msgRoot = MIMEMultipart('related') msgRoot['Subject'] = 'test message' #构造附件 att = MIMEText(open('h:\\python\\1.jpg', 'rb').read(), 'base64', 'utf-8') att["Content-Type"] = 'application/octet-stream' att["Content-Disposition"] = 'attachment; filename="1.jpg"' msgRoot.attach(att) smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msgRoot.as_string()) smtp.quit()
####群邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText sender = '***' receiver = ['***','****',……] subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msg = MIMEText('你好','text','utf-8') msg['Subject'] = subject smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()
####各种元素都包含的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart('alternative') msg['Subject'] = "Link" # Create the body of the message (a plain-text and an HTML version). text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" html = """\ <html> <head></head> <body> <p>Hi!<br> How are you?<br> Here is the <a href="http://www.python.org">link</a> you wanted. </p> </body> </html> """ # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(text, 'plain') part2 = MIMEText(html, 'html') # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(part1) msg.attach(part2) #构造附件 att = MIMEText(open('h:\\python\\1.jpg', 'rb').read(), 'base64', 'utf-8') att["Content-Type"] = 'application/octet-stream' att["Content-Disposition"] = 'attachment; filename="1.jpg"' msg.attach(att) smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()
####基于SSL的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header sender = '***' receiver = '***' subject = 'python email test' smtpserver = 'smtp.163.com' username = '***' password = '***' msg = MIMEText('你好','text','utf-8')#中文需参数‘utf-8’,单字节字符不需要 msg['Subject'] = Header(subject, 'utf-8') smtp = smtplib.SMTP() smtp.connect('smtp.163.com') smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.set_debuglevel(1) smtp.login(username, password) smtp.sendmail(sender, receiver, msg.as_string()) smtp.quit()

浙公网安备 33010602011771号