鱼C论坛

 找回密码
 立即注册
查看: 2141|回复: 5

[已解决]大佬们,快来救救孩子(邮箱读写)

[复制链接]
发表于 2021-6-28 11:34:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import email
  2. import poplib


  3. def decode(header: str):
  4.     value, charset = email.header.decode_header(header)[0]
  5.     if charset:
  6.         return str(value, encoding=charset)
  7.     else:
  8.         return value


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


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

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

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

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


  39. if __name__ == "__main__":
  40.     main()
复制代码


代码能跑通,附件能下载。但是我想被读取下载过附件的邮件,在下次访问的时候不在读取,应该怎么做?  读取邮件的正文,需要怎么做?
最佳答案
2021-6-28 12:37:53
本帖最后由 suchocolate 于 2021-6-28 12:54 编辑

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


  4. def decode(header: str):
  5.     value, charset = email.header.decode_header(header)[0]
  6.     if charset:
  7.         return str(value, encoding=charset)
  8.     else:
  9.         return value


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


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

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

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

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

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


  46. if __name__ == "__main__":
  47.     main()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-6-28 12:37:53 | 显示全部楼层    本楼为最佳答案   
本帖最后由 suchocolate 于 2021-6-28 12:54 编辑

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


  4. def decode(header: str):
  5.     value, charset = email.header.decode_header(header)[0]
  6.     if charset:
  7.         return str(value, encoding=charset)
  8.     else:
  9.         return value


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


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

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

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

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

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


  46. if __name__ == "__main__":
  47.     main()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-28 12:53:15 | 显示全部楼层
suchocolate 发表于 2021-6-28 12:37
加一个文件记录有无下载过

邮件正文怎么读取?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-28 13:05:50 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-6-28 17:12:23 | 显示全部楼层
suchocolate 发表于 2021-6-28 12:37
加一个文件记录有无下载过

大佬,有BUG, 我改成 message-id 了,能帮忙解释一下 pickle 的机制吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-28 19:32:30 | 显示全部楼层
z5560636 发表于 2021-6-28 17:12
大佬,有BUG, 我改成 message-id 了,能帮忙解释一下 pickle 的机制吗?

基本功能看教程:https://www.runoob.com/python3/python3-inputoutput.html
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-22 08:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表