python 学习笔记 Email

十七:电子邮件
                    一封电子邮件的旅程就是:发件人-->MUA-->MTA-->MTA-->若干个MTA-->MDA<--MUA<--收件人  
                    MTA:Mail Transfer Agent 邮件传输代理  MUA:Mail User Agent 邮件用户代理  MDA:Mail Delivery Agent 邮件投递代理
                    要编写程序来发送和接受邮件 本质上是:
                        1:编写MUA把邮件发送到MTA
                        2:编写MUA从MDA上收邮件
                    
                    1:SMTP发送邮件
                        SMTP是发送邮件的协议 Python内置对SMTP的支持 可以发送纯文本邮件 HTML文件以及带附件的邮件
                        Python对SMTP支持有smtplib 和email 两个模块 email负责构造邮件 smtplib 负责发送邮件
                        首先 我们来构造一个最简单的纯文本邮件:
                            from email.mime.text import MIMEText
                            msg=-MIMEText('Hello ,send by Python...','plain','utf-8')
                         注意到构造MIMEText对象时,第一个参数是邮件正文,第二个参数是MIME的subtype传入‘plain’最终的MIME就是‘text/plain’最后一定要用'urf-8'
                        然后通过SMTP发送出去
                            #输入Email的地址和口令
                            from_addr=raw_input('From:')
                            password=raw_input('Password:')
                            #输入SMTP服务器的地址
                            smtp_server=raw_input('SMTP server:')
                            #输入收件人地址
                            to_addr=raw_input('To:.....')
                
                            import smtplib
                            server=smtplib.SMTP(smtp_server,25)
                            server.set_debuglevel(1)
                            server.login(from_addr,password)
                            server.sendmail(from_addr,[to_addr],msg.as_tostring())
                            server.quit()

                        我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息 SMTP协议就是简单的文本命令和响应 login()方法用来登录SMTP服务器 sendmail()方法就是发邮件由于一次可以给多个人发 所以传入 的是一个list 邮件正文是一个str  as_tostring 把MIMETest 对象转化为一个str
                        如果一切顺利 就可以在收件人信箱里面收到我们刚发送的信息      
                        但是邮件1:没有主题 2:邮件人的名字没有显示为友好的名字 3:明明收到了邮件 却提示不在收件人中
                        我们需要把 from  to subject 添加到MIMETest中
                    
                            #-*-coding:utf-8-*-
                    
                            from email import encoders
                            from email.header import Header
                            from email.mime.text import MIMEText
                            from emial.utils import parseaddr,formataddr
                            import smtplib

                            def _format_addr(s):
                                name,addr=parseaddr(s)
                                return formataddr((\
                                    Header(name,'utf-8').encoding(),\
                                    addr.encoding('utf-8') if isinstance(addr,unicode) else addr))

                            from_addr=raw_input('From')
                            password=raw_input('Password: ')
                            to_addr=raw_input('To:')
                            smtp_server=raw_input('smtp server:')
                            
                            msg=MIMEText('hello ,send by Python ....','plain','utf-8')
                            msg['From']=_format_addr(u'Python 爱好者 <%s>' % from_addr)
                            msg['To'] = _format_addr(u'管理员 <%s>' % to_addr)
                            msg['Subject'] =Header(u'来自SMTP的问候','utf-8').encoding()
                
                             server=smtplib.SMTP(smtp_server,25)
                            server.set_debuglevel(1)
                            server.login(from_addr,password)
                            server.sendmail(from_addr,[to_addr],msg.as_tostring())
                            server.quit()

                    发送HTML邮件
                        如果要发送HTML邮件 而不是普通的纯文本文件 方法就是 在构造MIMEText对象时 把HTML字符串传进去 再把第二个参数由plain 变为 html 就可以了
                        msg=MIMEText('<html><body><h1>Hello</h1>'+'<p>send by <a href="http://www.baidu.com">Pytohn</a>...</p>'+'</body></html>','html','utf-8')  

                    发送附件: 如果要发送附件 可以构造一个MIMEMultipart 对象代表邮件本身 然后往里面加上一个MIMEText 作为邮件正文 在继续往里面加上表示附件的MIMEBase对象即可
                
                            #邮件对象
                            msg=MIMEMultipart()
                              msg['From']=_format_addr(u'Python 爱好者 <%s>' % from_addr)
                            msg['To'] = _format_addr(u'管理员 <%s>' % to_addr)
                            msg['Subject'] =Header(u'来自SMTP的问候','utf-8').encoding()
            
                            #邮件正文是MIMEText:
                            msg.attach( MIMEText('hello ,send by Python ....','plain','utf-8') )

                            #添加附件就是加上一个MIMEBase 从本地读取一个图片
                            with open('a.png','rb') as f:
                                #设置附件的MIME和文件名 这里是png类型:
                                mime=MIMEBase('image','png',filename='a.png')
                                #加上必要的头信息
                                mime.add_header('Content-Disposition','attachment',filename='a.png')
                                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)

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

                    发送图片:
                        如果要把一个图片嵌入到正文中怎么做  ?要把图片嵌入到正文中 我们只需要按照发送邮件的方式 先把邮件作为附件添加进去 然后在HTML中通过引用 src='cid=:0' 就可以把有附件作为图片嵌入了
                            msg.attach(MIMEText('<html><body><h1>Hello</h1><p><img src="cid:0"/></p></body></html>','html','utf-8'))

                    同时支持HTML和plain格式
                        如果收件人使用的设备太老看不了HTML邮件 将其自动降级为纯文本文件
                        利用MIMEMultipart 就可以组合一个HTML和plain 要注意subtype是alternative
                            msg=MIMEMultipart('alternative')
                            msg['From']=......
                            msg['To']=.....
                            msg['Subject']=.....
            
                            msg.attach(MIMEText('Hello','plain','utf-8'))
                            msg.attach( MIMEText('<html><body><h1>Hello</h1>'+'<p>send by <a href="http://www.baidu.com">Pytohn</a>...</p>'+'</body></html>','html','utf-8')   )
                            ........
        
                    加密SMTP
                        smtp_server='smtp.gmail.com'
                        smtp_port=587
                        server=smtplib.SMTP(smtp_server,smtp_port)
                        server.starttls()
                        ......
                        只要在创建了SMTP对象之后立即调用starttls方法 这样就创建了安全连接

                    2:接受邮件  POP3
                        接受邮件分为两步:1:用poplib 把邮件的原始文本下载到本地  2:用email解析原始文本 还原为邮件对象
                        
                        1:通过POP3 下载邮件
                            import poplib
            
                            #输入邮件地址,口令和POP3服务器地址:
                            email=raw_input('Email:...')
                            password=raw_input('Password')
                            pop3_server=raw_iinput('POP3 server..')
            
                            #连接到pop3 服务器
                            server=poplib.POP3(pop3_server)
                            #可以打开或者关闭调试信息
                            server.set_debuglevel(1)
                            #可选 打印POP3服务器欢迎文字
                            print(server.getwelcome())
                            #身份认知
                            server.user(email)
                            server.pass_(password)
                            #stat()返回邮件数量 和占用空间
                            print('Message:%s Size: %s' % server.stat())
                            #list() 返回所有邮件的编号
                            resp,mails.octets=server.list()
                            #可以查看邮件的列表 类似【1 82923  2 2184】
                            print mails
                            #获取最新的一封邮件 注意索引号从1开始
                            index=len(mails)
                            resp,lines,octets=server.retr(index)
                            #lines存储了邮件的原始文本的没一行
                            #可以获得整个邮件的原始文本
                            msg_content='\r\n'.join(lines)
                            #稍后解析邮件
                            msg=Parser().parsestr(msg_content)
                            #可以根据邮件索引号直接从服务器删除邮件
                            server.dele(index)
                            sever.quit()
                    解析邮件:
                        解析邮件的过程与发送邮件的过程正好相反 
                            import email
                            from email.parser import Parser
                            from email.header import decode_header
                            from email.utils import parseaddr
                        
                            #msg=Parser().parsestr(msg_content) 这个将邮件内容解析问一个Messge对象但是这个对象可能是MIMEMultipart 对象
                            
                            #indent用于缩进显示
                            def print_info(msg,indent=0):
                                if indent=0:
                                    #邮件的from to subject 存于根对象上
                                    for header in ['From','To','Subject']
                                        value=msg.get(header,'')
                                        if value:
                                            if header=="Subject":
                                                #需要解析subject 字符串
                                                value=decode_str(value)
                                            else:
                                                #需要解码Email地址
                                                hdr,addr=parseaddr(value)
                                                name=decode_str(hdr)
                                                value=u'%s <%s>' %(name,addr)
                                        print('%s%s:%s' % ('    '*indent,header,value))
                    
                                if (msg.is_multipart()):
                                    #如果对象是一个MIMEMultipart get_payload()返回list包含所有的子对象
                                    parts=msg.get_payload()
                                    for n,part in enumerate(parts):
                                        print('%spart %s' % ('    '*indent,n))
                                        print('%s-------------' % ('    '*indent ))
                                        #递归打印每一个子对象
                                        print_info(part,indent+1)
                                else:
                                    #邮件对象不是一个MIMEMultipart 就根据content_type判断
                                    content_type=msg.get_content_type()
                                    if content_type=='text/plain' or content_type='text/html':
                                        content=msg.get_payload(decode=True)
                                        #要检测文本编码
                                        charset=guess_charset(msg)
                                        if charset:
                                            content=content.decode(charset)
                                        print('%sText:%s' % ('    '*indent,content+'......'))
                                    else:
                                        #不是文本 作为附件处理
                                        print('%s Attachment:%s' % ('    '*indent,content_type))
            
                            def decode_str(s):
                                value,charset=decode_header(s)[0]
                                if charset:
                                    value=value.decode(charset)
                                return value

                            def guess_charset(msg):
                                #从msg对象获取编码
                                charset=msg.get_charset()
                                if charset is None:
                                    #如果没有 再从content_type 字段获取
                                    content_type=msg.get('Content-Type','').lower()
                                    pos=content_type.find('charset=')
                                    if pos>=0:
                                        charset=content_type[pos+8:].strip()
                                return charset

python模块详解 各个模块的详解 核心模块 1.1. 介绍 1.2. _ _builtin_ _ 模块 1.3. exceptions 模块 1.4. os 模块 1.5. os.path 模块 1.6. stat 模块 1.7. string 模块 1.8. re 模块 1.9. math 模块 1.10. cmath 模块 1.11. operator 模块 1.12. copy 模块 1.13. sys 模块 1.14. atexit 模块 1.15. time 模块 1.16. types 模块 1.17. gc 模块 更多标准模块 2.1. 概览 2.2. fileinput 模块 2.3. shutil 模块 2.4. tempfile 模块 2.5. StringIO 模块 2.6. cStringIO 模块 2.7. mmap 模块 2.8. UserDict 模块 2.9. UserList 模块 2.10. UserString 模块 2.11. traceback 模块 2.12. errno 模块 2.13. getopt 模块 2.14. getpass 模块 2.15. glob 模块 2.16. fnmatch 模块 2.17. random 模块 2.18. whrandom 模块 2.19. md5 模块 2.20. sha 模块 2.21. crypt 模块 2.22. rotor 模块 2.23. zlib 模块 2.24. code 模块 线程和进程 3.1. 概览 3.2. threading 模块 3.3. Queue 模块 3.4. thread 模块 3.5. commands 模块 3.6. pipes 模块 3.7. popen2 模块 3.8. signal 模块 数据表示 4.1. 概览 4.2. array 模块 4.3. struct 模块 4.4. xdrlib 模块 4.5. marshal 模块 4.6. pickle 模块 4.7. cPickle 模块 4.8. copy_reg 模块 4.9. pprint 模块 4.10. repr 模块 4.11. base64 模块 4.12. binhex 模块 4.13. quopri 模块 4.14. uu 模块 4.15. binascii 模块 文件格式 5.1. 概览 5.2. xmllib 模块 5.3. xml.parsers.expat 模块 5.4. sgmllib 模块 5.5. htmllib 模块 5.6. htmlentitydefs 模块 5.7. formatter 模块 5.8. ConfigParser 模块 5.9. netrc 模块 5.10. shlex 模块 5.11. zipfile 模块 5.12. gzip 模块 邮件和新闻消息处理 6.1. 概览 6.2. rfc822 模块 6.3. mimetools 模块 6.4. MimeWriter 模块 6.5. mailbox 模块 6.6. mailcap 模块 6.7. mimetypes 模块 6.8. packmail 模块 6.9. mimify 模块 6.10. multifile 模块 网络协议 7.1. 概览 7.2. socket 模块 7.3. select 模块 7.4. asyncore 模块 7.5. asynchat 模块 7.6. urllib 模块 7.7. urlparse 模块 7.8. cookie 模块 7.9. robotparser 模块 7.10. ftplib 模块 7.11. gopherlib 模块 7.12. httplib 模块 7.13. poplib 模块 7.14. imaplib 模块 7.15. smtplib 模块 7.16. telnetlib 模块 7.17. nntplib 模块 7.18. SocketServer 模块 7.19. BaseHTTPServer 模块 7.20. SimpleHTTPServer 模块 7.21. CGIHTTPServer 模块 7.22. cgi 模块 7.23. webbrowser 模块 国际化 8.1. locale 模块 8.2. unicodedata 模块 8.3. ucnhash 模块 多媒体相关模块 9.1. 概览 9.2. imghdr 模块 9.3. sndhdr 模块 9.4. whatsound 模块 9.5. aifc 模块 9.6. sunau 模块 9.7. sunaudio 模块 9.8. wave 模块 9.9. audiodev 模块 9.10. winsound 模块 数据储存 10.1. 概览 10.2. anydbm 模块 10.3. whichdb 模块 10.4. shelve 模块 10.5. dbhash 模块 10.6. dbm 模块 10.7. dumbdbm 模块 10.8. gdbm 模块 工具和实用程序 11.1. dis 模块 11.2. pdb 模块 11.3. bdb 模块 11.4. profile 模块 11.5. pstats 模块 11.6. tabnanny 模块 其他模块 12.1. 概览 12.2. fcntl 模块 12.3. pwd 模块 12.4. grp 模块 12.5. nis 模块 12.6. curses 模块 12.7. termios 模块 12.8. tty 模块 12.9. resource 模块 12.10. syslog 模块 12.11. msvcrt 模块 12.12. nt 模块 12.13. _winreg 模块 12.14. posix 模块 执行支持模块 13.1. dospath 模块 13.2. macpath 模块 13.3. ntpath 模块 13.4. posixpath 模块 13.5. strop 模块 13.6. imp 模块 13.7. new 模块 13.8. pre 模块 13.9. sre 模块 13.10. py_compile 模块 13.11. compileall 模块 13.12. ihooks 模块 13.13. linecache 模块 13.14. macurl2path 模块 13.15. nturl2path 模块 13.16. tokenize 模块 13.17. keyword 模块 13.18. parser 模块 13.19. symbol 模块 13.20. token 模块 其他模块 14.1. 概览 14.2. pyclbr 模块 14.3. filecmp 模块 14.4. cmd 模块 14.5. rexec 模块 14.6. Bastion 模块 14.7. readline 模块 14.8. rlcompleter 模块 14.9. statvfs 模块 14.10. calendar 模块 14.11. sched 模块 14.12. statcache 模块 14.13. grep 模块 14.14. dircache 模块 14.15. dircmp 模块 14.16. cmp 模块 14.17. cmpcache 模块 14.18. util 模块 14.19. soundex 模块 14.20. timing 模块 14.21. posixfile 模块 14.22. bisect 模块 14.23. knee 模块 14.24. tzparse 模块 14.25. regex 模块 14.26. regsub 模块 14.27. reconvert 模块 14.28. regex_syntax 模块 14.29. find 模块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值