python 邮箱自动化操作(1) 邮件的自动获取 imapclient 非常详细!有范例!!

这篇具有很好参考价值的文章主要介绍了python 邮箱自动化操作(1) 邮件的自动获取 imapclient 非常详细!有范例!!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

版本

python 3.8

imapclient:3.0.0 

注意: 这里是以腾讯企业邮箱为例,不同的邮箱可能会有不同的编码格式,就可能会产生错误。

邮件协议概述

  1. SMTP (Simple Mail Transfer Protocol)

    • SMTP 是用于发送电子邮件的标准协议。
    • 客户端使用 SMTP 将邮件发送到邮件服务器。
    • SMTP 客户端连接到 SMTP 服务器的 25 号端口。
    • SMTP 协议通常用于将邮件从发送方传输到接收方的邮件服务器。
  2. POP3 (Post Office Protocol version 3)

    • POP3 是用于从邮件服务器上获取邮件的协议。
    • 客户端使用 POP3 从邮件服务器下载邮件到本地计算机。
    • POP3 客户端连接到 POP3 服务器的 110 号端口。
    • POP3 协议通常会将邮件从服务器上下载到客户端,并在下载后从服务器上删除邮件。
  3. IMAP (Internet Message Access Protocol)

    • IMAP 也是用于从邮件服务器上获取邮件的协议,与 POP3 类似,但提供了更多的功能。
    • IMAP 允许客户端在多个设备上同步查看邮件,因为邮件仍然保留在服务器上。
    • IMAP 客户端连接到 IMAP 服务器的 143 号端口。
    • IMAP 协议通常更适合需要在多个设备上访问邮件的用户,因为它允许在所有设备上同步邮件状态。

这里列举了三种协议,其中SMTP用于发送邮件,POP3和IMAP用于获取邮件,由于IMAP更强大,所有本文的邮件获取也是基于IMAP协议。

从邮箱获取邮件 (标题、内容、附件等)

python虽然自带imaplib这个包,但用起来比较复杂,所以在这一部分,本文使用imapclient,这是一个用于 IMAP 客户端的第三方库,提供了更高级的功能,例如搜索、标记、文件夹管理等,它比标准库中的 imaplib 更易于使用。

1. 邮箱登录

from imapclient import IMAPClient

# 邮箱登录
email_address = 'xxxx@xxxx.com'  # 邮箱地址
password = 'xxxxxx'  # 密码
# 邮箱服务器信息
s_mail = IMAPClient('imap.exmail.qq.com')  # HOST = "imap.host.com"
s_mail.login(email_address, password)

2. 选择邮箱 select_folder

就是选择如下所示:

imapclient qq,python,自动化

可以先查看邮箱文件夹

imapclient qq,python,自动化

选择邮箱文件夹

# 选择邮箱
s_mail.select_folder(folder='inbox', readonly=True) # 这里folder也可以选择 已发送等

运行结果:

imapclient qq,python,自动化

这里可以看到,选择不同邮箱会收到不同的返回结果,返回的结果是字典格式的,一般不会用到,这里也没有去赋值。

3. 邮件筛选 search

在选择好邮箱之后,比如收件箱,会拿到大量的邮件,search我看代码可以根据标题、正文、时间、标记(‘SEEN’, 'UNSEEN', 'Flagged')等,但是实际上无法通过标题和正文检索,我想可能原因是跟邮箱编码格式有关,这里我查了很多资料依旧没有解决,但是可以通过遍历邮件的方法实现。

通过时间区间筛选  这里的时间要转换为datetime的格式  

# 从 20240101 这一天开始
message_ids = s_mail.search(['SINCE', datetime.date(2024, 1, 1)])
# 在 20240101 这一天之前 不包括20240101
message_ids = s_mail.search(['BEFORE', datetime.date(2024, 1, 1)])
# 在某个时间区间
since_date = datetime.datetime.strptime(search_date_since, '%Y%m%d')
before_date = datetime.datetime.strptime(search_date_before, '%Y%m%d')
message_ids = s_mail.search(['SINCE', since_date, 'BEFORE', before_date])

通过多个条件筛选 比如在上面的基础上加一个 “未读”

message_ids = s_mail.search(['SINCE', since_date, 'BEFORE', before_date, 'UNSEEN'])

4. 获取邮件数据 fetch

通过 fetch 方法,可以获取邮件的各种信息,如邮件的正文、发件人、收件人、主题、日期等。

以下是 imapclientfetch 方法的一般用法:

fetch_data = s_mail.fetch(message_ids, ['BODY[]', 'FLAGS', 'INTERNALDATE', 'RFC822.SIZE'])

这里的 message_ids 是一个邮件的序号或 UID 列表,用于指定要检索的邮件。第二个参数是一个列表,包含了你想要检索的邮件属性。常见的邮件属性包括:

  • 'BODY[]': 获取邮件的全部内容,包括头部和正文。
  • 'FLAGS': 获取邮件的标志,如已读、已删除等。
  • 'INTERNALDATE': 获取邮件的内部日期,即邮件的收到时间。
  • 'RFC822.SIZE': 获取邮件的大小。

除了以上列出的属性外,还可以指定其他属性,如 'BODY[HEADER]'(获取邮件的头部)、'ENVELOPE'(获取邮件的信封信息,如发件人、收件人、主题等)等。这里的细则可以查看这篇文章python imap fetch的坑

一般在使用的时候,可以根据需求选择属性,这样获取的数据量会小一点,速度会更快。

这里以‘BODY[]’举例,目的是介绍获取邮件全部内容后,如何获取邮件中各个属性的信息。

通过fetch(message_ids, ['BODY[]']) 获得是一个字典的格式,可以自行输出查看一下。

数据解析方法:

4.1 获取邮件头部信息

content = s_mail.fetch(uid, ['BODY[]'])[uid][b'BODY[]']
email_content = email.message_from_bytes(content)

# 第一种 解析 邮件头部信息 
# 像 收件人、发件人、抄送、标题等 这些都是同样的方式 所以以其中一种举例

# 定义解码函数  (这个)
def __decode_str__(hs):
    """
    编码处理
    :param hs:
    :return:
    """
    if isinstance(hs, bytes):
        hs = hs.decode()
    if hs:
        # loger.info(" ==== {}".format(hs[0]))
        if hs[0] == "=":
            s, de = decode_header(hs)[0]  # s is bytes    de='gbk'
            failout = base64.b64encode(s).decode()
            s = failout if not de else s.decode(de)  # str(s, 'gbk') = s.decode('gbk')
            return s
        else:
            return hs
    return ''

# 获取标题
subject = __decode_str__(email_content['Subject'])

'''
以下都可以通过上述方式获得
邮件头部信息:

Subject:邮件主题
From:发件人
To:收件人
Date:日期时间
Cc:抄送
Bcc:暗送
Message-ID:消息唯一标识符
In-Reply-To:回复邮件的消息标识符
References:参考消息标识符列表
'''

4.2 获取邮件正文

envelope = s_mail.fetch(uid, ['BODY[]'])[uid][b'BODY[]']
email_content = email.message_from_bytes(content)

# 提取邮件正文内容
if email_content.is_multipart():
    for part in email_content.walk():
        content_type = part.get_content_type()
        if content_type == 'text/plain':  # 只提取纯文本正文
            body = part.get_payload(decode=True).decode('gbk')
            print("邮件正文内容:")
            print(body)
            break
else:
    body = email_content.get_payload(decode=True).decode('gbk')
    print("邮件正文内容:")
    print(body)

4.3 获取邮件附件

for part in email_content.walk():
    fileName = part.get_filename()
    fileName = __decode_str__(fileName)
    print(fileName)
    # 附件下载
    for part in email_content.walk():
        fileName = part.get_filename()
        fileName = __decode_str__(fileName)
        if fileName:
            with open(fileName, 'wb') as f:
                data = part.get_payload(decode=True)
                f.write(data)

邮件检索 (遍历)

上述三种方法没有办法直接获取目标邮件的指定信息的功能,由1select_flod,2search两种方法,我们也只可以获得一个范围,在search函数中,可以看到subject字段,但是可能由于邮箱的问题,没有达到通过标题筛选的效果。所以邮件检索的方法,可以理解为在一个范围内遍历邮箱。

当邮箱邮件数很多的时候,这个找到目标邮件的方法会很慢,这里有一个小技巧,就是比如通过标题找到目标邮件时,可以在fetch中选择 'BODY[HEADER]',这样数据量相对较小,速度会稍微快一点。

以下是一个范例 (可以直接使用)

获取一个时间区间内的所有邮件,然后通过标题筛选,再拿到目标附件。

search_data_since、search_date_before: 字符串 like:'20240101'文章来源地址https://www.toymoban.com/news/detail-855285.html

def get_excel_from_mail(search_date_since, search_date_before, target_subject, target_filename):
    # 邮箱登录
    print("email login...")
    email_address = 'xxx@xxx.com'
    password = 'xxxxxxx'
    # 邮箱服务器信息
    # 搜索邮件
    s_mail = IMAPClient('imap.exmail.qq.com')
    s_mail.login(email_address, password)
    s_mail.select_folder('收件箱', readonly=True)
    since_date = datetime.datetime.strptime(search_date_since, '%Y%m%d').date()

    # 指定日期范围为since_date到since_date的后一天
    next_day = datetime.datetime.strptime(search_date_before, '%Y%m%d').date()
    result = s_mail.search(['SINCE', since_date, 'BEFORE', next_day])
    print('SINCE', since_date, 'BEFORE', next_day)
    for uid in reversed(result):  # 优先获取最新的邮件
        try:
            subject = s_mail.fetch(uid, ['ENVELOPE'])[uid][b'ENVELOPE']

            subject = __decode_str__(subject.subject)
            print(subject)
            if target_subject not in str(subject):
                continue
        except Exception as e:
            print(e)
            # print(s_mail.fetch(uid, ['ENVELOPE']))
            continue


        massageList = s_mail.fetch(uid, ['BODY[]'])
        mailBody = massageList[uid][b'BODY[]']
        # 邮件内容解析最里面那层是按字节来解析邮件主题内容,这个过程生成Message类型
        try:
            email_content = email.message_from_string(mailBody)
        except TypeError:
            email_content = email.message_from_bytes(mailBody)

        for part in email_content.walk():
            fileName = part.get_filename()
            fileName = __decode_str__(fileName)

            # print('fileName', fileName)
            if fileName == target_filename:
                print(' OK   Subject = {}'.format(subject))
                print('邮件附件下载')
                # 附件下载
                for part in email_content.walk():
                    fileName = part.get_filename()
                    fileName = __decode_str__(fileName)
                    if fileName == target_filename:
                        # savefile = os.path.join(dirs_email, fileName)
                        # with open(savefile, 'wb') as f:
                        # print('--------savefile')
                        data = part.get_payload(decode=True)  # 获取excel内容 保存文件  -----
                        # f.write(data)
                        return data
    return False


def __decode_str__(hs):
    """
    编码处理
    :param hs:
    :return:
    """
    if isinstance(hs, bytes):
        hs = hs.decode()
    if hs:
        # loger.info(" ==== {}".format(hs[0]))
        if hs[0] == "=":
            s, de = decode_header(hs)[0]  # s is bytes    de='gbk'
            failout = base64.b64encode(s).decode()
            s = failout if not de else s.decode(de)  # str(s, 'gbk') = s.decode('gbk')
            return s
        else:
            return hs
    return ''

到了这里,关于python 邮箱自动化操作(1) 邮件的自动获取 imapclient 非常详细!有范例!!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Selenium+python怎么搭建自动化测试框架、执行自动化测试用例、生成自动化测试报告、发送测试报告邮件

    本人在网上查找了很多做自动化的教程和实例,偶然的一个机会接触到了selenium,觉得非常好用。后来就在网上查阅各种selenium的教程,但是网上的东西真的是太多了,以至于很多东西参考完后无法系统的学习和应用。 以下整理的只是书中自动化项目的知识内容,介绍怎么搭

    2024年02月05日
    浏览(67)
  • Python办公自动化 -- Python发送电子邮件和Outlook的集成

    Python办公⾃动化是利⽤Python编程语⾔来创建脚本和程序,以简化、加速和⾃动化⽇常办公任务和⼯作流程的过程。它基于Python的强⼤功能和丰富的第三⽅库,使得能够处理各种办公任务,如⽂档处理、数据分析、电⼦邮件管理、⽹络通信等等。 要使⽤Python发送电⼦邮件,可以

    2024年02月20日
    浏览(62)
  • 【苹果】SpringBoot监听Iphone15邮件提醒,Selenium+Python自动化抢购脚本

    Iphone15来了,两年之约你还记得吗? 遂整合之前iphone13及iphone14的相关抢购代码,完成一个 SpringBoot监听Iphone15有货邮件提醒+python自动化脚本 小功能。 后端基于 SpringBoot ,通过 苹果官网进行有货接口调用 ,将 JSON结果解析分析 是否有货,并展示近10条有货记录列;可灵活监听

    2024年02月08日
    浏览(52)
  • 全网最详细的Python自动化测试+邮件推送+企业微信推送+Jenkins

    什么是python自动化?我理解的Python自动化测试就是把以前人为测试转化为机器测试的一种过程。自动化测试是一种比手工测试更快获得故障反馈的方法。 自动化测试是一种质量保障的方式,最重要的还是以做好一款高质量产品为前提。测试工作很多时候就是在不断平衡质量、

    2024年02月03日
    浏览(41)
  • 自动化测试(二)selenium八大获取元素方法及对象操作

    目录 webdriver API 脚本实例 元素的定位 1. 通过id定位: 2. 通过name方式定位 3. 通过tag name(标签名)定位 4. 通过class name (类名)方式定位 5. 通过CSS 方式定位 6. 通过xpath方式定位 7. link text定位 8. Partial link text 定位 操作测试对象  鼠标点击与键盘输入 submit 提交表单 text 获取

    2024年02月03日
    浏览(46)
  • Selenium 自动化 —— 实战篇之自动登录163邮箱

    Selenium 自动化专栏系列文章 (一)入门和 Hello World 实例 (二)使用WebDriverManager自动下载驱动 (三)Selenium IDE录制、回放、导出Java源码 (四)浏览器窗口操作 (五)切换浏览器窗口 (六)定位页面元素 前面的系列文章已经对 WebDriver 驱动管理、浏览器窗口操作、页面元素

    2024年04月13日
    浏览(39)
  • Python操作自动化

    迷途小书童 读完需要 3 分钟 速读仅需 1 分钟 当我们需要自动化进行一些重复性的任务时,Python 中的 pyautogui 库就可以派上用场了,这个库可以模拟鼠标和键盘的操作,让我们的程序可以像人一样与计算机进行交互。 首先,我们需要安装 pyautogui 库。在命令行中输入以下命令

    2024年02月07日
    浏览(39)
  • python 自动化学习(四) pyppeteer 浏览器操作自动化

    背景 之前我在工作中涉及到了很多地方都是重复性的页面点点点工作,又因为安全保密原则不开放接口和数据库,只有一个页面来提供点击进行操作,就想着用前面学的自动化来实现,但发现前面学的模拟操作对浏览器来说并没有那么友好,而后改用“selenium”,但是存在一

    2024年02月12日
    浏览(44)
  • python微信PC端自动化-获取聊天记录

    目前已有许多微信客户端的自动化工具,可供我们自动获取聊天记录、发送消息等等。不过微信网页版现在已无法登录,因此一些python库如itchat、wxpy等已经无法使用了(基于网页)。 现在有大佬开发出了一个好玩的微信自动化python库——wxauto。wxauto基于uiautomation、win32gui等自

    2024年02月03日
    浏览(55)
  • python 自动化学习(三) 句柄获取、模拟按键、opencv安装

         句柄是在操作系统中的一种标识符,相当于我们每个人的身份证一样,句柄在电脑中也是有唯一性的,我们启动的每一个程序都有自己的句柄号,表示自己的身份     为什么要说句柄,我们如果想做自动化操作时,肯定也不想程序占用了我们整个电脑,稍微操作一下

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包