This commit is contained in:
2026-01-30 11:28:35 +08:00
commit f1831c31b4
399 changed files with 860978 additions and 0 deletions
+248
View File
@@ -0,0 +1,248 @@
{
"cells": [
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-03T07:13:02.829703Z",
"start_time": "2025-04-03T07:12:52.594728Z"
}
},
"cell_type": "code",
"source": [
"# 输入自己163的邮箱地址。\n",
"user_email_address ='zhangyang@f6car.cn'\n",
"# 邮箱的授权码,注意:不是登录密码\n",
"user_password = 'Zy18742526670'\n",
"# 这个是163邮箱的pop3的服务器地址,各个公司的邮箱平台的POP3的服务器地址都是不同的,自己网上查询下即可\n",
"# 例如:qq邮箱的pop3服务器地址是:pop.qq.com\n",
"pop_server_host = 'pop.qiye.aliyun.com'\n",
"# 邮箱对应的pop服务器的监听端口\n",
"# (如果设置POP3的SSL加密方式连接的话,则端口为:995),否则就是端口为110\n",
"pop_server_port ='995'\n",
"send_name = \"曹伟\"\n",
"\n",
"\n",
"def connect_email_by_pop3():\n",
" try:\n",
" # 连接pop服务器。如果没有使用SSL,将POP3_SSL()改成POP3(),且监听端口改为:110即可\n",
" email_server = poplib.POP3_SSL(host=pop_server_host, port=pop_server_port, timeout=10)\n",
" print(\"连接pop服务器-------正常,开始验证用户邮箱\")\n",
" except:\n",
" print(\"连接pop服务器-------异常,退出\")\n",
" exit(1)\n",
" try:\n",
" # 验证用户邮箱\n",
" email_server.user(user_email_address)\n",
" print(\"用户邮箱验证-------正常,开始验证邮箱授权码\")\n",
" except:\n",
" print(\"用户邮箱验证-------异常,退出\")\n",
" exit(1)\n",
" try:\n",
" # 验证邮箱密码是否正确,注意不是登录密码,是授权码\n",
" email_server.pass_(user_password)\n",
" print(\"邮箱授权码验证-------正常,开始接受邮箱以及附件\")\n",
" except:\n",
" print(\"邮箱授权码验证-------异常,退出\")\n",
" exit(1)\n",
" # 开始处理邮箱相关信息\n",
" parse_email_server(email_server)\n",
"\n",
"\n",
"def parse_email_server(email_server):\n",
" resp, mails, octets = email_server.list()\n",
" num, total_size = email_server.stat()\n",
" # mails存储了邮件编号列表,\n",
" index = len(mails)\n",
" # 倒序遍历邮件\n",
" for i in range(index, 0, -1):\n",
" # 倒序遍历邮件,这样取到的第一封就是最新邮件\n",
" resp, lines, octets = email_server.retr(i)\n",
" # lines存储了邮件的原始文本的每一行,\n",
" # 邮件的原始文本:# lines是邮件内容,列表形式使用join拼成一个byte变量\n",
" msg_content = b'\\r\\n'.join(lines).decode('utf-8')\n",
" # 解析邮件:\n",
" msg = Parser().parsestr(msg_content)\n",
" # 邮件时间,解析时间格式\n",
" mail_datetime = parse_mail_time(msg.get(\"date\"))\n",
" un_mail_time = int(mail_datetime.timestamp())\n",
" un_now = int(time.time())\n",
" yu_now = un_now - (un_now % 86400)\n",
" max_mail_time_str = datetime.strftime(mail_datetime, '%Y-%m-%d %H:%M:%S')\n",
" # 这个可以作为根据时间进行邮件的过滤解析,这个把时间写死判断,比较局限,可以在第一个接收时,把最新的邮件接收时间写入到自定义的文件中,\n",
" # 等第二次接收邮件时,再取文件中的时间,进行判断,用于过滤\n",
" if un_mail_time < yu_now: # 邮件接受时间为今天的时间,则进行解析,否则跳过\n",
" continue\n",
" print(\"邮件接收时间为:\" + max_mail_time_str)\n",
" # 解析邮件具体内容,包括正文,标题,和附件\n",
" parser_content(msg, 0)\n",
" # 别忘记退出\n",
" email_server.quit()\n",
"\n",
"\n",
"def parser_content(msg, indent):\n",
" if indent == 0:\n",
" # 邮件的From, To, Subject存在于根对象上:\n",
" # 调用解析邮件头部内容的函数\n",
" parser_email_header(msg)\n",
"\n",
" # 解析发送人信息\n",
" hdr, addr = parseaddr(msg['From'])\n",
" # name 发送人邮箱名称, addr 发送人邮箱地址\n",
" name, charset = decode_header(hdr)[0]\n",
" if charset:\n",
" name = name.decode(charset)\n",
" print('发送人邮箱名称: {0},发送人邮箱地址: {1}'.format(name, addr))\n",
" \n",
" if name == send_name:\n",
" # 下载附件\n",
" for part in msg.walk():\n",
" file_name = part.get_filename() # 获取附件名称类型\n",
" if file_name is None:\n",
" continue\n",
" # 说明不是文本,则作为附件处理\n",
" filename = decode_str(file_name) # 对附件名称进行解码\n",
" data = part.get_payload(decode=True) # 下载附件\n",
" att_file = open(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\email' + filename, 'wb') # 在指定目录下创建文件,注意二进制文件需要用wb模式打开\n",
" att_file.write(data) # 保存附件\n",
" att_file.close()\n",
" print(\"附件:\" + filename + \"保存成功!\")\n",
"\n",
" if (msg.is_multipart()):\n",
" # 如果邮件对象是一个MIMEMultipart,\n",
" # get_payload()返回list,包含所有的子对象:\n",
" parts = msg.get_payload()\n",
" for n, part in enumerate(parts):\n",
" # 递归打印每一个子对象:\n",
" return parser_content(part, indent + 1)\n",
" else:\n",
" # 解析正文\n",
" content_type = msg.get_content_type()\n",
" if content_type == 'text/plain' or content_type == 'text/html':\n",
" # 纯文本或HTML内容:\n",
" content = msg.get_payload(decode=True)\n",
" # 要检测文本编码:\n",
" charset = guess_charset(msg)\n",
" if charset:\n",
" content = content.decode(charset)\n",
" print('%s正文内容为: %s' % (' ' * indent, content))\n",
"\n",
"\n",
"# 解析邮件\n",
"def parser_email_header(msg):\n",
" # 解析邮件标题\n",
" subject = msg['Subject']\n",
" value, charset = decode_header(subject)[0]\n",
" if charset:\n",
" value = value.decode(charset)\n",
" print('邮件标题: {0}'.format(value))\n",
"\n",
" # 解析发送人信息\n",
" hdr, addr = parseaddr(msg['From'])\n",
" # name 发送人邮箱名称, addr 发送人邮箱地址\n",
" name, charset = decode_header(hdr)[0]\n",
" if charset:\n",
" name = name.decode(charset)\n",
" print('发送人邮箱名称: {0},发送人邮箱地址: {1}'.format(name, addr))\n",
"\n",
" # 解析接收人信息\n",
" hdr, addr = parseaddr(msg['To'])\n",
" # name 发送人邮箱名称, addr 发送人邮箱地址\n",
" name, charset = decode_header(hdr)[0]\n",
" if charset:\n",
" name = name.decode(charset)\n",
" print('接收人邮箱名称: {0},接收人邮箱地址: {1}'.format(name, addr))\n",
"\n",
"\n",
"# 解码\n",
"def decode_str(s):\n",
" value, charset = decode_header(s)[0]\n",
" if charset:\n",
" value = value.decode(charset)\n",
" return value\n",
"\n",
"\n",
"# 猜测字符编码\n",
"def guess_charset(msg):\n",
" # 先从msg对象获取编码:\n",
" charset = msg.get_charset()\n",
" if charset is None:\n",
" # 如果获取不到,再从Content-Type字段获取:\n",
" content_type = msg.get('Content-Type', '').lower()\n",
" for item in content_type.split(';'):\n",
" item = item.strip()\n",
" if item.startswith('charset'):\n",
" charset = item.split('=')[1]\n",
" break\n",
" return charset\n",
"\n",
"\n",
"# 邮件时间处理函数\n",
"# POP3Post Office Protocol 3),即邮局协议的第3个版本,\n",
"# 是电子邮件的第一个离线协议标准。该协议把邮件下载到本地计算机,\n",
"# 不与服务器同步,缺点是更易丢失邮件或多次下载相同的邮件。\n",
"import poplib\n",
"# 引入用来解析邮件相关信息的模块\n",
"import time\n",
"from email.parser import Parser\n",
"from email.header import decode_header\n",
"from email.utils import parseaddr\n",
"# 引入相关时间库\n",
"from datetime import datetime\n",
"def parse_mail_time(mail_datetime):\n",
" GMT_FORMAT = \"%a, %d %b %Y %H:%M:%S\"\n",
" GMT_FORMAT2 = \"%d %b %Y %H:%M:%S\"\n",
" index = mail_datetime.find(' +0')\n",
" if index > 0:\n",
" mail_datetime = mail_datetime[:index] # 去掉+0800\n",
" formats = [GMT_FORMAT, GMT_FORMAT2]\n",
" for ft in formats:\n",
" try:\n",
" mail_datetime = datetime.strptime(mail_datetime, ft)\n",
" return mail_datetime\n",
" except:\n",
" pass\n",
" raise Exception(\"邮件时间格式解析错误\")\n",
"\n",
"\n",
"# 比较规范写法,象征着程序入口\n",
"if __name__ == \"__main__\":\n",
" connect_email_by_pop3()\n",
"\n"
],
"id": "844482dd689ee68c",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"连接pop服务器-------正常,开始验证用户邮箱\n",
"用户邮箱验证-------正常,开始验证邮箱授权码\n",
"邮箱授权码验证-------正常,开始接受邮箱以及附件\n"
]
}
],
"execution_count": 1
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}