Python邮件收发(SMTP POP3)

时间:2022-12-06 19:03:42
SMTP邮件发送
   SMTP(Simple Mail Transfer Protocol) 简单邮件传输协议。
   smtplib模块
   创建SMTP对象
    
    
   
   
  1. smtplib.SMTP( [host [, port [, local_hostname]]] )
  2. 参数:
  3.    host : SMTP 服务器主机。可以指定主机的ip地址或域名,可选参数。
  4.    port : host参数需指定SMTP使用端口(25)
  5.    local_hostname : SMTP在本机时,指定localhost
    SMTP对象方法 
     
     
    
    
  1. 方法 描述
  2. SMTP.set_debuglevel(level) 设置输出debug调试信息,默认不输出
  3. SMTP.docmd(cmd[, argstring]) 发送一个命令到SMTP服务器
  4. SMTP.connect([host[, port]]) 连接到指定的SMTP服务器
  5. SMTP.helo([hostname]) 使用helo指令向SMTP服务器确认你的身份
  6. SMTP.ehlo(hostname) 使用ehlo指令像ESMTPSMTP扩展)确认你的身份
  7. SMTP.ehlo_or_helo_if_needed() 如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo()
  8. SMTP.has_extn(name) 判断指定名称是否在SMTP服务器上
  9. SMTP.verify(address) 判断邮件地址是否在SMTP服务器上
  10. SMTP.starttls([keyfile[, certfile]]) 使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密
  11. SMTP.login(user, password) 登录SMTP服务器
  12. SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) 发送邮件
  13. from_addr:邮件发件人
  14. to_addrs:邮件收件人
  15. msg:发送消息
  16. SMTP.quit() 关闭SMTP会话
  17. SMTP.close() 关闭SMTP服务器连接
   1.文件形式邮件
   
   
  
  
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.header import Header
  6. mail_server = 'smtp.163.com'
  7. mail_server_port = 465
  8. mail_user = 'msun1996@163.com'
  9. mail_pass = '*******'
  10. from_addr = 'msun1996@163.com'
  11. to_addr = ['msun1996@163.com'] #to_addr可放入多个邮箱,以逗号隔开
  12. #发送邮件形式和内容
  13. msg = MIMEText('Python mail test...','plain','utf-8')
  14. msg['From'] = Header('msun','utf-8')
  15. msg['To'] = Header('Test','utf-8')
  16. #发送主题
  17. subject = 'Python SMTP mail test'
  18. msg['Subject'] = Header(subject,'utf-8')
  19. try:
  20. smtp = smtplib.SMTP_SSL(mail_server,mail_server_port)
  21. smtp.login(mail_user,mail_pass)
  22. smtp.sendmail(from_addr,to_addr,msg.as_string())
  23. smtp.quit()
  24. print('邮件发送成功')
  25. except smtplib.SMTPException:
  26. print('Error:邮件发送失败!!!')
   注意:此处用的是465端口 ssl
   问题1:阿里云默认是关闭25端口,醉了!怪不得windose 25端口可以,linux就不行了。
   问题2:windose smtp对象定义格式如下可以
    
    
   
   
  1. smtp = smtplib.SMTP_SSL()
  2. smtp.connect(mail_server,mail_server_port)
        linux下必须用以下格式,否则会有ssl报错
    
    
   
   
  1. smtp = smtplib.SMTP_SSL(mail_server,mail_server_port)
   (163邮箱默认没开代理的,要进行设置)
    2.HTML形式邮件
    
    
   
   
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.header import Header
  6. mail_server = 'smtp.163.com'
  7. mail_server_port = 465
  8. mail_user = 'msun1996@163.com'
  9. mail_pass = '******'
  10. from_addr = 'msun1996@163.com'
  11. to_addr = ['msun1996@163.com']
  12. mail_msg='''
  13. <p>Python 邮件发送测试...</p>
  14. <p><a href="http://139.199.82.84/kexiewojia/">这是一个链接</a></p>
  15. '''
  16. msg = MIMEText(mail_msg,'html','utf-8')
  17. msg['From'] = Header('msun','utf-8')
  18. msg['To'] = Header('Test','utf-8')
  19. subject = 'Python SMTP mail test'
  20. msg['Subject'] = Header(subject,'utf-8')
  21. try:
  22. smtp = smtplib.SMTP_SSL(mail_server,mail_server_port)
  23. smtp.login(mail_user,mail_pass)
  24. smtp.sendmail(from_addr,to_addr,msg.as_string())
  25. smtp.quit()
  26. print('邮件发送成功')
  27. except smtplib.SMTPException:
  28. print('Error:邮件发送失败!!!')
   3.邮件附件
    
    
   
   
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.header import Header
  6. from email.mime.multipart import MIMEMultipart
  7. mail_server = 'smtp.163.com'
  8. mail_server_port = 465
  9. mail_user = 'msun1996@163.com'
  10. mail_pass = '******'
  11. from_addr = 'msun1996@163.com'
  12. to_addr = ['msun1996@163.com']
  13. #创建一个带附件实例
  14. msg = MIMEMultipart()
  15. msg['From'] = Header('msun','utf-8')
  16. msg['To'] = Header('Test','utf-8')
  17. subject = 'Python SMTP mail test'
  18. msg['Subject'] = Header(subject,'utf-8')
  19. #邮件正文
  20. msg.attach(MIMEText('Ptthon SMTP mail test...','plain','utf-8'))
  21. #构造附件
  22. att = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
  23. att["Content-Type"] = 'application/octet-stream'
  24. att["Content-Disposition"] = 'attachment; filename="test.txt"'
  25. msg.attach(att)
  26. try:
  27. smtp = smtplib.SMTP_SSL(mail_server,mail_server_port)
  28. smtp.login(mail_user,mail_pass)
  29. smtp.sendmail(from_addr,to_addr,msg.as_string())
  30. smtp.quit()
  31. print('邮件发送成功')
  32. except smtplib.SMTPException:
  33. print('Error:邮件发送失败!!!')
   4.邮件图片(图片存放于附件中)
    
    
   
   
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.header import Header
  6. from email.mime.multipart import MIMEMultipart
  7. from email.mime.image import MIMEImage
  8. mail_server = 'smtp.163.com'
  9. mail_server_port = 465
  10. mail_user = 'msun1996@163.com'
  11. mail_pass = '******'
  12. from_addr = 'msun1996@163.com'
  13. to_addr = ['msun1996@163.com']
  14. msg = MIMEMultipart()
  15. msg['From'] = Header('msun','utf-8')
  16. msg['To'] = Header('Test','utf-8')
  17. subject = 'Python SMTP mail test'
  18. msg['Subject'] = Header(subject,'utf-8')
  19. msgAlternative = MIMEMultipart('alternative')
  20. msg.attach(msgAlternative)
  21. mail_msg = '''
  22. <p>Python SMTP mail test...</p>
  23. <p>图片</p>
  24. <img src='cid:image' width='30' height='30'>
  25. '''
  26. #邮件正文
  27. msg.attach(MIMEText(mail_msg,'html','utf-8'))
  28. #指定图片为当前目录
  29. fp = open('logo.png','rb')
  30. msgImage = MIMEImage(fp.read())
  31. fp.close()
  32. #定义图片ID,在HTML引用
  33. msgImage.add_header('Content-ID','<image>')
  34. msg.attach(msgImage)
  35. try:
  36. smtp = smtplib.SMTP_SSL(mail_server,mail_server_port)
  37. smtp.login(mail_user,mail_pass)
  38. smtp.sendmail(from_addr,to_addr,msg.as_string())
  39. smtp.quit()
  40. print('邮件发送成功')
  41. except smtplib.SMTPException:
  42. print('Error:邮件发送失败!!!')


POP3收取邮件
   pop3收取步骤:
      1.用poplib模块把源始文件下载到本地
      2.用email模块解析原始文本,还原邮件对象
   poplib模块
   poplib建立对象
     
     
    
    
  1. poplib.POP3(server)
  2.    server : pop服务器对象
   poplib对象方法
     
     
    
    
  1. user(username) 发送用户名到服务器,等待服务器返回信息
  2. pass_(password) 密码
  3. stat() 返回邮箱的状态,返回2元祖(消息的数量,消息的总字节)
  4. list([msgnum]) stat()的扩展,返回一个3元祖(返回信息, 消息列表, 消息的大小),如果指定msgnum,就只返回指定消息的数据
  5. retr(msgnum) 获取详细msgnum,设置为已读,返回3元组(返回信息, 消息msgnum的所以内容, 消息的字节数),如果指定msgnum,就只返回指定消息的数据
  6. dele(msgnum) 将指定消息标记为删除
  7. quit() 登出,保存修改,解锁邮箱,结束连接,退出
    pop接收实例
     
     
    
    
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. import poplib
  4. from email.parser import Parser
  5. from email.header import decode_header
  6. from email.utils import parseaddr
  7. from datetime import datetime
  8. email = 'msun1996@163.com'
  9. passwd = 'h19960304'
  10. pop_server = 'pop.163.com'
  11. def get_email():
  12. server = poplib.POP3_SSL(pop_server,'995')
  13. # 可以打开或关闭调试信息:
  14. # server.set_debuglevel(1)
  15. # 可选:打印POP3服务器的欢迎文字:
  16. print(server.getwelcome().decode('utf-8'))
  17. server.user(email)
  18. server.pass_(passwd)
  19. #邮件数量和占有空间
  20. print('Messages: %s. Size: %s' % server.stat())
  21. #list()返回所有邮件编号
  22. resp_one,mails,octets_one = server.list()
  23. #查看返回列表
  24. #print(mails)
  25. #获取最新的一封邮件,索引号为1开始
  26. index = len(mails)
  27. resp_two, lines, octets_two = server.retr(index)
  28. #lines存储邮件原始文本每行并进行解析
  29. msg_content = b'\r\n'.join(lines).decode('utf-8')
  30. msg = Parser().parsestr(msg_content)
  31. #可以根据邮件索引从服务器删除邮件
  32. #server.dele(index)
  33. #关闭邮件
  34. server.quit()
  35. print_info(msg)
  36. #编码设置
  37. def guess_charset(my_msg):
  38. charset = my_msg.get_charset()
  39. if charset is None:
  40. content_type = my_msg.get('Content-Type', '').lower()
  41. pos = content_type.find('charset=')
  42. if pos >= 0:
  43. charset = content_type[pos + 8:].strip()
  44. return charset
  45. def decode_str(s):
  46. value, charset = decode_header(s)[0]
  47. if charset:
  48. value = value.decode(charset)
  49. return value
  50. # indent用于缩进显示,递归打印
  51. def print_info(my_msg, indent=0):
  52. if indent == 0:
  53. for header in ['From', 'To','Subject']:
  54. value = my_msg.get(header, '')
  55. if value:
  56. if header == 'Subject':
  57. value = decode_str(value)
  58. else:
  59. hdr, addr = parseaddr(value)
  60. name = decode_str(hdr)
  61. value = u'%s <%s>' % (name, addr)
  62. print('%s%s: %s' % (' ' * indent, header, value))
  63. if my_msg.is_multipart():
  64. parts = my_msg.get_payload()
  65. for n, part in enumerate(parts):
  66. print('%spart %s' % (' ' * indent, n))
  67. print('%s-----------------------------------' % ' ' * indent)
  68. print_info(part, indent + 1)
  69. else:
  70. content_type = my_msg.get_content_type()
  71. if content_type == 'text/plain' or content_type == 'text/html':
  72. content = my_msg.get_payload(decode=True)
  73. charset = guess_charset(my_msg)
  74. if charset:
  75. content = content.decode(charset)
  76. print('%sText: %s' % (' ' * indent, content + '...'))
  77. else:
  78. print('%sAttachment: %s' % (' ' * indent, content_type))
  79. if __name__ == '__main__':
  80. get_email()

   
学习博客: http://www.liaoxuefeng.com