Python3 imap pop3、邮箱自动下载附件,分析邮件内容



背景需求

每小时定时拉取指定邮箱的未读邮件内容:

内容包括:邮件主题,发送人,收件人,抄送人,邮件时间,邮件正文内容,对应的附件文件列表


经过调研,可使用pop3和imap实现

一、imap、pop3是什么?

1. POP3

POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上,比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的 。
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

2. imap

IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。
同时,IMAP像POP3那样提供了方便的邮件下载服务,让用户能进行离线阅读。IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定。此外,IMAP 更好地支持了从多个不同设备中随时访问新邮件。

3. 技术选型

生产环境使用imap实现,因为涉及到标记已读未读

二、代码示例

1.imap

几乎每一行都有注释,看注释应该就懂

import email
from email.utils import parseaddr
import imaplib
from email.header import decode_header
import os
import time
import urllib.request

# 邮箱用户名
email_user = ''

# 进入邮箱->设置->账户->开启imap 会生成一个授权码
password = ''

#QQ的imap接收邮件服务器。我用的qq,其他邮箱自查一下
imap_server = 'imap.qq.com'

# 当前目录,用于存放附件文件路径
save_path = os.getcwd()+"/data"

def email_process(email_user, password, imap_server):
    # 这里的服务器根据需要选择
    server = imaplib.IMAP4_SSL(imap_server)
    
    # 登录imap,使用纯文本密码标识客户。 password 将被转码
    server.login(email_user, password)
    
    # 选择邮箱文件夹,没有则创建,此段用来测试,可忽略
    """ destmailbox = 'CaiZiXi'
    rsp, msgs = server.select(destmailbox)
    print(rsp)
    if (rsp == 'NO'):
        server.create(destmailbox)
        print('IMAP: create mail box ' + destmailbox) """
 
    # 邮箱中的文件夹,默认为'INBOX'(收件箱),不需要改
    rsp, inbox = server.select("INBOX")

    # 搜索匹配的邮件,第一个参数是字符集,None默认就是ASCII编码,第二个参数是查询条件
    # 这里的ALL就是查找全部,UNSEEN 为标识未读 SEEN 为已读
    # 生成环境用的是未读UNSEEN,读取完毕设置该邮件为已读,这样下次读取不会重复读取
    type, data = server.search(None, "ALL")

    # 邮件列表,使用空格分割得到邮件索引
    msgList = data[0].split()

	# 附件文件名称,根据实际需要设置
    attachment_files = []

    #遍历所有邮件
    for i in range(0, len(msgList)):

        # 改变邮箱中消息的旗标处理,设置为已读,可放在下载完附近或读取内容使用
        #server.store(msgList[i], '+FLAGS', '\\SEEN')
        
        # server.copy(msgList[i], "优快云") 测试copy邮件用
        type, datas = server.fetch(msgList[i], '(RFC822)')
        
        # 使用utf-8 解码
        text = datas[0][1].decode('utf8')
        
        # 转化为email.message对象
        msg = email.message_from_string(text)
        
        From = parseaddr(msg.get('from'))[1]  # 发件人
        To = parseaddr(msg.get('To'))[1]  # 收件人
        Cc = parseaddr(msg.get_all('Cc'))[1]  # 抄送人
        Subject = decode_str(parseaddr(msg.get('Subject'))[1])  # 主题

        # 获取邮件时间,格式化收件时间
        date1 = time.strptime(msg.get("Date")[0:24], '%a, %d %b %Y %H:%M:%S')
        # 邮件时间格式转换
        date2 = time.strftime("%Y-%m-%d", date1)
        print(f'发件人:{From};收件人:{To};抄送人:{Cc};主题:{Subject};收件日期:{date1}')

		#这里接收附件和正文内容
        for part in msg.walk():
            file_name = part.get_filename()
            if file_name:
                file_name = decode_str(file_name)
                data = part.get_payload(decode=True)
                #保存附件文件
                att_file = open(os.path.join(save_path, file_name), 'wb')
                attachment_files.append(file_name)
                att_file.write(data)
                att_file.close()
                print(f"附件 {file_name} 下载完成")
            elif not part.is_multipart():
            	#打印会有两个内容,一个纯文本,一个html文本
                print(part.get_payload(decode=True).decode('utf-8'))

"""字符编码转换"""
def decode_str(s):
    value, charset = decode_header(s)[0]
    if charset:
        value = value.decode(charset)
        return value


if __name__ == '__main__':
    print("start")
    email_process(email_user, password, imap_server)
    print("end")

建议对着官方网站来理解 https://docs.python.org/zh-cn/3.7/library/imaplib.html?highlight=imaplib#imap4-example
里面有最简单的示例

2.pop3简单示例

代码如下(示例):

# 导入库——qq邮箱测试,其他邮箱略有差异
import poplib
import email
import datetime
import time
import traceback
import sys
import telnetlib
import zipfile
import os
import shutil
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr

# 输入邮件地址, 口令和POP3服务器地址:
email_user = ''

# 此处密码是授权码,用于登录第三方邮件客户端
password = ''

pop3_server = 'pop.qq.com'

# 授权码登录邮箱
def email_login(email_user, password, pop3_server):
    # 连接到POP3服务器,有些邮箱服务器需要ssl加密,可以使用poplib.POP3_SSL
    telnetlib.Telnet('pop.qq.com', 995)
    server = poplib.POP3_SSL(pop3_server, 995, timeout=50)

    # server=poplib.POP3(pop3_server,110,timeout=10)
    # 可以打开或关闭调试信息
    #server.set_debuglevel(1)

    # 身份认证:
    server.user(email_user)
    server.pass_(password)

    # 返回邮件数量和占用空间:
    print('Messages: %s. Size: %s' % server.stat())

    # list()返回所有邮件的编号:
    resp, mails, octets = server.list()

    return mails, server

def decode_str(str_in):
    """字符编码转换"""
    value, charset = decode_header(str_in)[0]
    if charset:
        value = value.decode(charset)
    return value
   
def save_att_file(msg, save_path):
    """附件下载函数"""
    for part in msg.walk():
        file_name = part.get_filename()
        # contentType = part.get_content_type()
        attachment_files =[]
        if file_name:
            file_name = decode_str(file_name)
            data =  part.get_payload(decode=True)
            # print("emailcontent:\r\n"+data.decode('unicode_escape'))
            att_file = open(os.path.join(save_path,file_name), 'wb')
            attachment_files.append(file_name)
            att_file.write(data)
            att_file.close()
            print(f"附件 {file_name} 下载完成")

def main(inday):
    # 遍历所有邮件
    for i in range(4,len(mails)+1):
        resp,lines,octets = server.retr(i)
        
        msg_content=b'\r\n'.join(lines).decode('unicode_escape')

        # 解析邮件:
        msg = Parser().parsestr(msg_content)
        #print(msg)

        From = parseaddr(msg.get('from'))[1]#发件人
        To = parseaddr(msg.get('To'))[1]#收件人
        Cc = parseaddr(msg.get_all('Cc'))[1]#抄送人
        Subject = decode_str(parseaddr(msg.get('Subject'))[1])#主题
       
        # 获取邮件时间,格式化收件时间
        date1 = time.strptime(msg.get("Date")[0:24],'%a, %d %b %Y %H:%M:%S')
        # 邮件时间格式转换
        date2 = time.strftime("%Y-%m-%d %H:%M:%S",date1)
        """ if date2 <= "2022-09-18":
            continue

        print(Subject)
        print(date2)
        break """
        print(f'发件人:{From};收件人:{To};抄送人:{Cc};主题:{Subject};收件日期:{date2}')

        # 主题和日期验证所需邮件
        if ("iam" in Subject)&(date2 == inday):
            save_att_file(msg, save_path)
      
# 今天日期
today = datetime.date.today()
inday = today.strftime('%Y-%m-%d')

# 昨天日期
yesterday = (today - datetime.timedelta(days=1)).strftime('%Y-%m-%d')

#当前目录
save_path = os.getcwd()

# 登录获取邮件列表
mails,server = email_login(email_user,password,pop3_server)

# 下载主程序
main(inday)


总结

日常工作中用到的PHP居多,python少用,有啥不对的可以讨论

Ceph是一个广泛使用的分布式存储系统,它可以在大规模的硬件集群上运行,并提供对象存储、块存储和文件存储等多种数据存储方式。下面是一个Ceph分布式存储详细安装教程: 1. 安装Ceph软件包 在安装Ceph之前,需要添加Ceph软件包的源。可以使用以下命令添加Ceph源: ``` sudo apt-get install wget wget -q -O- 'https://download.ceph.com/keys/release.asc' | sudo apt-key add - echo deb https://download.ceph.com/debian-{ceph-stable-release}/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list ``` 注意:上面的`{ceph-stable-release}`需要替换为你要安装的Ceph版本,例如:`luminous`、`mimic`等。 添加源之后,执行以下命令安装Ceph软件包: ``` sudo apt-get update sudo apt-get install ceph-deploy ceph-mds ceph-mon ceph-osd ``` 2. 配置Ceph集群 在安装Ceph软件包之后,需要配置Ceph集群。可以使用`ceph-deploy`工具来配置集群。首先需要创建一个新的Ceph集群,可以使用以下命令: ``` mkdir my-cluster cd my-cluster ceph-deploy new {ceph-mon-node1} {ceph-mon-node2} {ceph-mon-node3} ``` 注意:上面的`{ceph-mon-node1}`、`{ceph-mon-node2}`和`{ceph-mon-node3}`需要替换为实际的Ceph Monitor节点IP地址或主机名。 执行以上命令后,会在`my-cluster`目录下生成一个`ceph.conf`配置文件和一个`ceph-deploy-ceph.log`日志文件。需要对`ceph.conf`文件进行一些修改,以便于Ceph集群正常运行。 在`ceph.conf`文件中,需要添加以下配置项: ``` fsid = {cluster-fsid} mon_initial_members = {ceph-mon-node1},{ceph-mon-node2},{ceph-mon-node3} mon_host = {ceph-mon-node1},{ceph-mon-node2},{ceph-mon-node3} public_network = {public-network} cluster_network = {cluster-network} ``` 注意:上面的`{cluster-fsid}`需要替换为一个UUID字符串,可以使用以下命令生成: ``` uuidgen ``` 注意:上面的`{ceph-mon-node1}`、`{ceph-mon-node2}`和`{ceph-mon-node3}`需要替换为实际的Ceph Monitor节点IP地址或主机名。`{public-network}`和`{cluster-network}`需要替换为实际的网络地址段。`{public-network}`是Ceph集群的公共网络地址,`{cluster-network}`是Ceph集群的集群网络地址。 然后需要在Ceph Monitor节点上初始化集群,可以使用以下命令: ``` ceph-deploy mon create-initial ``` 执行以上命令后,Ceph集群就初始化完成了。 3. 添加Ceph OSD节点 Ceph OSD是Ceph集群中的存储节点,可以使用以下命令添加Ceph OSD节点: ``` ceph-deploy osd create {osd-node1}:{osd-device1}:{osd-device2} {osd-node2}:{osd-device1}:{osd-device2} ... ``` 注意:上面的`{osd-node1}`、`{osd-node2}`等需要替换为实际的Ceph OSD节点IP地址或主机名。`{osd-device1}`和`{osd-device2}`需要替换为实际的磁盘设备路径。 执行以上命令后,Ceph OSD节点就添加完成了。 4. 添加Ceph MDS节点 Ceph MDS是Ceph集群中的元数据服务器,可以使用以下命令添加Ceph MDS节点: ``` ceph-deploy mds create {mds-node} ``` 注意:上面的`{mds-node}`需要替换为实际的Ceph MDS节点IP地址或主机名。 执行以上命令后,Ceph MDS节点就添加完成了。 5. 校验Ceph集群 在添加完Ceph节点之后,可以使用以下命令校验Ceph集群是否正常运行: ``` ceph -s ``` 如果Ceph集群正常运行,则会显示一些基本信息,例如:Ceph Monitor节点数量、Ceph OSD节点数量、Ceph MDS节点数量、存储池数量等。 以上就是Ceph分布式存储详细安装教程,如果你想要更详细的了解Ceph的配置和使用,可以参考Ceph官方文档。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值