办公自动化——谁没发周报?

博主分享了如何使用Python自动化检查员工周报发送情况,从收件箱中筛选出未发送周报的人员名单。过程中遇到的挑战包括邮件包的使用、数据类型转换和文件操作。通过编写和运行脚本,不仅提升了Python技能,还显著减轻了工作负担,减少了焦虑感。遇到的错误包括数据维度和类型不匹配,以及邮件获取不全等问题,通过调整方法和错误处理得以解决。
摘要由CSDN通过智能技术生成

1. 需求背景

作为上市公司最有价值的员工,每周都需要检查几十个人谁没发周报。

就是这么“有”意义的工作!我打算把我自己迭代了。

周报是通过腾讯企业邮箱发送的,必须以周报为标题的邮件。

而我的任务是从需要发周报的人里,一个一个排查出谁没发周报。

每次做之前都很抗拒,很焦虑。

但在写完这个脚本之后,初运行的第一周,感觉非常之愉悦,心情都有变好。

2. 收获:

  • 练习了python的基础语法
  • 应用难点在于对于包的掌握和应用,以及细节处理,比如数据类型之间的转换
  • <Life is short, You need Python>

3. 实现步骤

自从0基础学了Python基础,也对这个任务的半自动化实现方式有了初步的实现步骤:
1、生成《已交周报名单》

2、对比《需要交周报的名单》

3、生成《需要提醒名单》

4. 知识储备

这里可能会用到代码“工具”:

  • python基础、
  • email的imaplib包的导入和关于邮件的导入发送相关方法
  • 文件读取存储
  • 数据类型之间的转换以及列表运算

在写代码的过程中,深刻地体会到了,为什么程序员总是被吐槽:

你今天又写了多少行bug!

所以放代码之前,总结一下这 3 天碰到的坑(坑是程序员宝贵的经验,多总结应该对我有好处)

5. 可能会遇到的bug

代码很简单,IMAPlib包第一次使用还是很不好上手的,经常出现的错误就在取数上:

比如:

取值时注意统一好【数值】的【类型】(可计算)和【维度】:
【维度】报错:列表和列表(同类型数值类型)计算的时候,需要注意取值不能再取[列表],一维列表不能和二维列表[[列表]]进行计算;

【类型】报错:文件读取时读取的是字符串,但是进行计算需要将字符串转换成可计算的列表,常出现带字符\n,无法直接装进列表里,需要split方法分割成,“逗号”,才能转化成列表

...此处省略层级错误等低水平错误×10084...

Error+10086 :

因为文件被拖动到文件夹下,他获取到的数可能为空,为假值,执行系统就会报错TypeError:'NoneType' object is not subscriptable

解决办法 :用if条件+continue来跳过空置(如果数值为空,则跳过本次循环,遍历下一个)

Error+10087 :发现获取的邮件不全,
解决办法 :找IMAP官方问到,换一个取数的方法(.uid——>.search)

以下是完整的源代码+IMAP的官方说明文档:imaplib --- IMAP4 协议客户端 — Python 3.7.13 說明文件

import imaplib, email, os
import re

import chardet

imapserver = 'imap.exmail.qq.com'
emailuser = "waXXXXXg@XXXX.cn"
emailpasswd = "XXXX44"

attachementdir = r"d:\a"  # 附件存放的位置

conn = imaplib.IMAP4_SSL(imapserver, 993)
conn.login(emailuser, emailpasswd)
conn.list()  # 列出邮箱中所有的列表,如:收件箱、垃圾箱、草稿箱。。。

# conn.select('INBOX')  # 选择收件箱(默认)
conn.select()  # 选择收件箱(默认)

# result, dataid = conn.uid('search', None, '(SUBJECT "周报")')  error:用.uid的结果是周报获取不全——>获取的方法可能有问题,得找另一个,就找到了.search
# word = "周报"
# w = word.encode("utf-8")

result, dataid = conn.search('UTF-8', "SUBJECT", str("周报".encode()))  #这里的str(),参数是字符串形式的编码

mailidlist = dataid[0].split()  # 转成标准列表,获得所有邮件的ID


# 解析邮件内容
def get_body(msg):
    if msg.is_multipart():
        return get_body(msg.get_payload(0))
    else:
        return msg.get_payload(None, decode=True)


# search('FROM','abc@outlook.com',conn)  根据输入的条件查找特定的邮件
def search(key, value, conn):
    result, data = conn.search(None, key, '"()"'.format(value))
    return data


# 获取附件
def get_attachements(msg):
    for part in msg.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue
        filename = part.get_filename()

        if bool(filename):
            filepath = os.path.join(attachementdir, filename)
            with open(filepath, 'wb') as f:
                f.write(part.get_payload(decode=True))
some_people = []
pattern = re.compile(r"[<](.*?)[>]", re.S)

for id in mailidlist:
    result, data = conn.fetch(id, '(RFC822)')  # 通过邮件is2 {'"=?utf-8?B?546L562x5am3?=" <wangxiaoting@itcast.cn>', '=?GBK?B?yr+087fy?= <aijiangyouxid获取邮件
    # e =  email.message_from_bytes(data[0][1])
    data_01 = data[0]
    # print(data_01)
    if data_01 is None:
        continue
    # charset = chardet.detect(data[0][1])['encoding']
    e = email.message_from_string(data[0][1].decode('utf-8'))
    subject = email.header.make_header(email.header.decode_header(e['SUBJECT']))
    b = e['From']
    a = email.header.decode_header(e['From'])

点个小赞攒,鼓励一下吧~

欢迎评论区交流,吐槽

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值