z5560636 发表于 2021-6-28 11:34:27

大佬们,快来救救孩子(邮箱读写)

import email
import poplib


def decode(header: str):
    value, charset = email.header.decode_header(header)
    if charset:
      return str(value, encoding=charset)
    else:
      return value


def download_attachment(msg):
    subject = decode(msg.get('Subject'))# 获取消息标题
    for part in msg.walk():# 遍历整个msg的内容
      if part.get_content_disposition() == 'attachment':
            attachment_name = decode(part.get_filename())# 获取附件名称
            attachment_content = part.get_payload(decode=True)# 下载附件
            attachment_file = open('./' + attachment_name, 'wb') # 在指定目录下创建文件,注意二进制文件需要用wb模式打开
            attachment_file.write(attachment_content)# 将附件保存到本地
            attachment_file.close()
    print('Done………………', subject)


def main():
    """连接到POP3服务器"""
    server = poplib.POP3(host='pop.qiye.aliyun.com')# 创建一个POP3对象,参数host是指定服务器

    """身份验证"""
    server.user('*')# 参数是你的邮箱地址
    server.pass_('*')# 参数是你的邮箱密码,如果出现poplib.error_proto: b'-ERR login fail',就用开启POP3服务时拿到的授权码

    """获取邮箱中消息(邮件)数量"""
    msg_count, _ = server.stat()
    print(msg_count,_)
    """遍历消息并保存附件"""
    for i in range(msg_count):
      """获取消息内容:POP3.retr(which)检索index为which的整个消息,并将其设为已读"""
      _, lines, _ = server.retr(
            i+1)# 3个结果分别是响应结果(1个包含是否请求成功和该消息大小的字符串),消息内容(一个字符串列表,每个元素是消息内容的一行),消息大小(即有多少个octets,octet特指8bit的字节)

      """将bytes格式的消息内容拼接"""
      msg_bytes_content = b'\r\n'.join(lines)
      """将字符串格式的消息内容转换为email模块支持的格式(<class 'email.message.Message'>)"""
      msg = email.message_from_bytes(msg_bytes_content)
      """下载消息中的附件"""
      download_attachment(msg)


if __name__ == "__main__":
    main()


代码能跑通,附件能下载。但是我想被读取下载过附件的邮件,在下次访问的时候不在读取,应该怎么做?读取邮件的正文,需要怎么做?

suchocolate 发表于 2021-6-28 12:37:53

本帖最后由 suchocolate 于 2021-6-28 12:54 编辑

加一个文件记录有无下载过
import email
import poplib
import pickle   # <===== 加pickle模块


def decode(header: str):
    value, charset = email.header.decode_header(header)
    if charset:
      return str(value, encoding=charset)
    else:
      return value


def download_attachment(msg, db):   # <===== 传入db
    subject = decode(msg.get('Subject'))# 获取消息标题
    for part in msg.walk():# 遍历整个msg的内容
      if part.get_content_disposition() == 'attachment':
            if subject not in db:   # <===== db中没有就下载,有就不下载
                attachment_name = decode(part.get_filename())# 获取附件名称
                attachment_content = part.get_payload(decode=True)# 下载附件
                attachment_file = open('./' + attachment_name, 'wb')# 在指定目录下创建文件,注意二进制文件需要用wb模式打开
                attachment_file.write(attachment_content)# 将附件保存到本地
                attachment_file.close()
                db.append(subject)   # <===== 下载完后加入到db
    print('Done………………', subject)
    return db   # <===== 记得返回db


def main():
    """连接到POP3服务器"""
    server = poplib.POP3(host='pop.qiye.aliyun.com')# 创建一个POP3对象,参数host是指定服务器

    """身份验证"""
    server.user('*')# 参数是你的邮箱地址
    server.pass_('*')# 参数是你的邮箱密码,如果出现poplib.error_proto: b'-ERR login fail',就用开启POP3服务时拿到的授权码

    """获取邮箱中消息(邮件)数量"""
    msg_count, _ = server.stat()
    print(msg_count, _)

    db = pickle.load(open("db.pkl", "rb"))   # <===== 打开db文件,没有的话可以提前手工建一个空白列表的pickle文件:pickle.dump([], open("db.pkl", "wb"))
   
    """遍历消息并保存附件"""
    for i in range(msg_count):
      """获取消息内容:POP3.retr(which)检索index为which的整个消息,并将其设为已读"""
      _, lines, _ = server.retr(
            i + 1)# 3个结果分别是响应结果(1个包含是否请求成功和该消息大小的字符串),消息内容(一个字符串列表,每个元素是消息内容的一行),消息大小(即有多少个octets,octet特指8bit的字节)

      """将bytes格式的消息内容拼接"""
      msg_bytes_content = b'\r\n'.join(lines)
      """将字符串格式的消息内容转换为email模块支持的格式(<class 'email.message.Message'>)"""
      msg = email.message_from_bytes(msg_bytes_content)
      """下载消息中的附件"""
      db = download_attachment(msg, db)   # <===== 传入db
    pickle.dump(db, open("db.pkl", "wb"))   # <===== 最后保存db


if __name__ == "__main__":
    main()

z5560636 发表于 2021-6-28 12:53:15

suchocolate 发表于 2021-6-28 12:37
加一个文件记录有无下载过

邮件正文怎么读取?

suchocolate 发表于 2021-6-28 13:05:50

z5560636 发表于 2021-6-28 12:53
邮件正文怎么读取?

基本功能看教程:https://www.kancloud.cn/thinkphp/python-guide/39542

z5560636 发表于 2021-6-28 17:12:23

suchocolate 发表于 2021-6-28 12:37
加一个文件记录有无下载过

大佬,有BUG, 我改成 message-id 了,能帮忙解释一下 pickle 的机制吗?

suchocolate 发表于 2021-6-28 19:32:30

z5560636 发表于 2021-6-28 17:12
大佬,有BUG, 我改成 message-id 了,能帮忙解释一下 pickle 的机制吗?

基本功能看教程:https://www.runoob.com/python3/python3-inputoutput.html
页: [1]
查看完整版本: 大佬们,快来救救孩子(邮箱读写)