python进阶宝典17- 收发邮件

一. 发送电子邮件SMTP

二.用IMAP获取和操作电子邮件

三. 例子: 向会员发送会费提醒电子邮件

四. 另一个涉及中文转化的例子

具体内容见代码及相关注释。

## 发送电子邮件SMTP
import smtplib
smtpObj = smtplib.SMTP('mail.testmail.com',25)   # 创建对象,建立服务器连接
# 如果SMTP()调用不成功,那么SMTP服务器可能不支持TLS端口587。可以尝试利用SMTP_SSL()和465端口创建对象。
# smtpObj = smtplib.SMTP_SSL('mail.testmail.com',465)
type(smtpObj)                   # <class 'smtplib.SMTP'>
smtpObj.ehlo()                  # 连接smtp第一步,返回元组第一项是 250 表示问候成功
smtpObj.starttls()              # 连接加密, 成功则返回元组第一项是 220。SMTP_SSL模式则跳过这一步
smtpObj.login('[email protected]','passstr')  # 成功则返回元组第一项是 235
smtpObj.sendmail('[email protected]','[email protected]','Subject:Test.\nThis is a test.\nDo not reply.')
smtpObj.sendmail('[email protected]','[email protected],[email protected]','Subject:Test2.\nThe test2,two addresses.')
# 发信人;收信人列表;邮件正文必须以Subject:Test.\n开头,其中Test是标题,后面为具体内容了
# {}  - sendmail()的返回值是一个字典。对于电子邮件发送失败的每个收件人,字典中有一个键值对。空则表示全部发生成功
smtpObj.quit()                  # 连接断开

## 用IMAP获取和操作电子邮件
# python自带有 imaplib, 这里使用第三方更好用的 imapclient 及 pyzmail(解析与转换邮件格式)
import imapclient
imapObj = imapclient.IMAPClient('mail.testmail.com',port=995,ssl=True)
imapObj.login('[email protected]','MY_pass')
import pprint
pprint.pprint(imapObj.list_folders())  # 显示邮箱文件夹
imapObj.select_folder('INBOX',readonly=True)   # 选择邮箱文件夹,如果要在获取邮件时标记为已读,要用readonly=False
import imaplib
imaplib._MAXLINE = 10000000            # 配置内存大小,防止搜索匹配大量邮件时异常
UIDs = imapObj.search(['SINCE 05-Jul-2017','FROM [email protected]'])   # 搜索邮件ID,返回该邮箱自该日期以来的所有
rawMessages = imapObj.fetch(UIDs,['BODY[]'])   # 读取邮件内容
pprint.pprint(rawMessages)
imapObj.select_folder('INBOX',readonly=False)
UIDs = imapObj.search(['ON 05-Jul-2017'])      # 返回当日所有邮件ID 
UIDs
imapObj.delete_messages(UIDs)         # 给邮件打上Deleted标志
imapObj.expunge()                     # 永久删除带Deleted标志的邮件
imapObj.logout()

## 例子: 向会员发送会费提醒电子邮件
# 用openpyxl从Excel中读取数据
# 找出上月没有交费的所有会员--创建一个字典,包含会费超期会员
# 找到他们的email地址,向他们发送邮件提醒
#
# Sends emails based on payment status in spreadsheet.

import openpyxl,smtplib,sys
# Open the spreadsheet and get the latest dues status.
wb = openpyxl.load_workbook('emailCustoms.xlsx')
sht = wb.get_sheet_by_name('Sheet1')
lastCol = sht.max_column
latestMonth = sht.cell(row=1,column=lastCol).value
# Check each member's payment status. 
unpaidMembers = {}
for r in range(2,sht.max_row + 1):
    payment = sht.cell(row=r,column=lastCol).value
    if payment != 'paid':
        name = sht.cell(row=r,column=1).value
        email = sht.cell(row=r,column=2).value
        unpaidMembers[name] = email
# Log in email account.
smtpObj = smtplib.SMTP('mail.testmail.com',25)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('[email protected]',sys.argv[1])
# Send out reminder emails. 
for name,email in unpaidMembers.items():
    body = '"Subject: %s dues unpaid.\nDear %s,\nRecords show that you have not paid dues for %s. \
    Please make this payment as soon as possible.Thank you!" % (latestMonth,name,latestMonth)'
    print('Sending email to %s...' % email)
    sendmailStatus = smtpObj.sendmail('[email protected]',email,body)
    if sendmailStatus != {}:
        print('There was a problem sending email to %s: %s' % (email,sendmailStatus))
smtpObj.quit()
## 例子2
#-*- encoding: utf-8 -*-
#-*- encoding: gbk -*-

# 因为可能会用到中文,所以必须有上面的这两句话

# 引入模块及IMAPClient类
import getpass, email, sys
from imapclient import IMAPClient

hostname = 'imap.gmail.com' #gmail的smtp服务器网址
username = '[email protected]'
passwd = '***'

c = IMAPClient(hostname, ssl= True) # 通过一下方式连接smtp服务器,没有考虑异常情况,详细请参考官方文档
try:
    c.login(username, passwd) #登录个人帐号
except c.Error:
    print('Could not log in')
    sys.exit(1)
else:
    c.select_folder('INBOX', readonly = True) 
# 利用select_folder()函数进行文件夹,'INBOX'为收件箱,readonly = True 表明只读并不修改任何信息

    result = c.search('UNSEEN')
    msgdict = c.fetch(result, ['BODY.PEEK[]'] ) 

# 现在已经把邮件取出来了,下面开始解析邮件
    for message_id, message in msgdict.items():
        e = email.message_from_string(message['BODY[]']) # 生成Message类型

     # 由于'From', 'Subject' header有可能有中文,必须把它转化为中文
        subject = email.header.make_header(email.header.decode_header(e['SUBJECT']))
        mail_from = email.header.make_header(email.header.decode_header(e['From']))
     
     # 解析邮件正文
        maintype = e.get_content_maintype()
        if maintype == 'multipart':
            for part in e.get_payload():
                if part.get_content_maintype() == 'text':
                    mail_content = part.get_payload(decode=True).strip()
        elif maintype == 'text':
            mail_content = e.get_payload(decode=True).strip()

     # 此时,需要把content转化成中文,利用如下方法:        
        try:
            mail_content = mail_content.decode('gbk')
        except UnicodeDecodeError:
            print('decode error')
            sys.exit(1)
        else:
            print('new message')
            print('From: ', mail_from)
            print('Subject: ', subject)
            getstr = input('if you wanna read it, input y: ')
            if getstr.startswith('y'):
                print('-'*10, 'mail content', '-'*10)
                print(mail_content.replace('<br>', '\n'))
                print('-'*10, 'mail content', '-'*10)
finally:
  c.logout()


猜你喜欢

转载自blog.csdn.net/ebzxw/article/details/80686027
今日推荐