使用Python读取网易邮箱大师客户端的所有邮件以及邮箱验证码
本帖最后由 我真的爱发明 于 2022-12-31 18:36 编辑# 1. 前言
- 现在绝大多数的网站注册的时候,都需要你提供手机或者邮箱的验证码。如果只是想要注册一两个账号,那么随便接一下验证码就可以了。但如果我们想要注册几十个账号,意味着你需要接受几十个验证码,这可能就是一个不小的灾难了。你首先得从几十个邮箱中找到这个特定的邮箱,点开它上面的收件箱,然后复制验证码.......
- ![](https://remnote-user-data.s3.amazonaws.com/ntCWP6tib5795KW7ggCVvgFBmkr0FlFlidZ7pyfoS2jLhxWZqAXrbLmcNWHzvPSEnKgoEHaoC9jVOw9dtc_ALnpBrlf3UCVwuBn9cY-ecdK0JBRX2dYpIyxTakyNu-6d.png)
- 可能这么说一下,大家不觉得有啥,但实际操作起来真的是太烦人类了。于是我想着能不能解析一下网易邮箱大师上面的API来直接读取邮件内容或者验证码呢?于是便有了下面的项目。
# 2. 效果
- 可以直接通过Python代码或者命令行程序直接读取网易邮箱大师的本地客户端邮件数据
- ![](https://remnote-user-data.s3.amazonaws.com/OsX_bRcPuGf36ys2nql5_8p92arxWvu_FUs1g-sw-ib5L8TC__vFA3ZMPSWr6XP4cyIjXgQhU1YsvxFvhLllrDZQWwZXW9baovx44nQGU0ilXeqiVigBG0qkwjhQZ8gV.png)
###
# 3. 探究过程
- 想要读取网易邮箱上的邮件要么是通过API进行调用,要么是通过客户端本地的数据进行逆向获取
- 经过一番百度以及一番初步尝试,发现网易邮箱并没有给用户或者开发者提供程序API接口,那这是否就意味着我们想要用程序读取网易邮箱中的邮件呢做不到呢?其实并不然,就算没有上层的API,但我们可以读取底层的保存数据(只要他没有太高难度的加密就行),于是便有了下面的尝试
## 3.1. 找到本地存储的数据库
- 那么首先需要找到网易邮箱大师的数据存储位置
- 系统设置这里可以看到网易邮箱的数据存储位
![](https://remnote-user-data.s3.amazonaws.com/RKpocDcgoBDlQOLGxgzfj8D2L5BK9gkf_FsBOyUp5F1W_YRTbi_8EVv2-4XNBZaN6JaAXFtjsJhf1hVlVT78saOxpKfWOFOdVsg77tw-m5eaBCuavtsufLjR0kSHTD4O.png)
- 打开位置之后,是一系列以邮箱名命名的文件夹
![](https://remnote-user-data.s3.amazonaws.com/valP6cCOsyyhazal56da2m7ciGSlMiRhC3tk2EC7goYm7g-3uGNClMK7XXYgOmTvG5n4mgT2HtjQz_x440LGq6nOEioJm6JjJQikJVpe7DqVU_lvZ6RSUYVouNjRD_nm.png)
- 但是这里面的数据似乎是加密的数据库文件
![](https://remnote-user-data.s3.amazonaws.com/F2PvLUISRrabpwBe7vokIZb_vRGLDHbRdpGlvbbFk46U4rCv5HvjsogQr57o0fDpPn4Kt2nBF0plIB0U2VP5t2uVjsYCm1koIsxENPaD2gRABh7XfazXPZq0sDlnjMYw.png)
- 自己使用Navicat for sqlite打开发现也看不到里面的具体数据
![](https://remnote-user-data.s3.amazonaws.com/aS8aLGdMkzlx4WUcKybjOm4Jd2CN9-xHMA4VqkViwYa0uykB4jtwZZtd43jVba1r6fe1Ct7NNPt76jiTmW8190q24aR9-XwmSDGLt8QqGvy7SuKx2Q-XdgreLD2O_Uqa.png)
- 自己又换了一个db文件进行读取发现里面的数据似乎也并未完全加密,依稀可以看到一些邮件内容之前之所以显示是乱码,可能是转码的问题
![](https://remnote-user-data.s3.amazonaws.com/UZftVHIVW25PH2ZHPyYRte_gGrYypw4-xK0cRtD0TlmnhPgWCykL-2Dk_GmKpav5JBNcepgXzxWmdtJ7qxct7urCB6DRK_u4IAOKIyUmWBAvvQPFyfh488p9TbDoJz8R.png)
- 自己又查看了一下另外两个mail和search ,没想到邮件内容直接是在**search/search_content**中明文存储,看来今天的探索应该可以结束了
![](https://remnote-user-data.s3.amazonaws.com/KtpKVDuE2_exRQPVDUeFxE2V1QNembEIWEZWUhDnTTRpnPhux7HYTd9GsQwdeeJuULy1fOuQgOLmPZ4FSKsYuSgBkVG-pOOfBQCt9vCuw2FfHRQR_pb4W6Ar4Hu6oICQ.png)
- 我们来新发一份邮件,看能否实时更新
![](https://remnote-user-data.s3.amazonaws.com/W0ZJ3P55Dcs6BMzHuhmZn1MoMufklHjyCGy4mPoKWjq7T_ScK7_9qY-Wq5QWg34g0dDMb5DkMvzhFDcIT6hpkb2IkVhM44waOnavCyaOm0dcUAFyqWqb1MFKWLv9YrSk.png)
可能是自己添加的邮箱数量太多了,这里一直处于发送过程中
![](https://remnote-user-data.s3.amazonaws.com/YObsHcIG5ImCJ0_jzGMYNu7ULn-A8ULtQ2clWlQ_7DhiSPm7obfMBzcytCcOx4Pj1O3OpaDiiZeCvANSerz5uwViA3Q9_TR9VB1tNyKz5odxaS19JGaGk-50N2m6jtqW.png)
重启了一下网易邮箱客户端之后正常了
- 刷新了一下Navicat for sqlite,然后看到了我们刚才测试的数据
![](https://remnote-user-data.s3.amazonaws.com/mThbopOowXJ-fBHWjlvqO7DoyHv_FVfUFL1y83nsqDl4m8GaIcvX7gIijFJEwmel-7aTf-ySQyYZ4SagZApYqjb6I_8KZfrtsCfgISfeB3h9IK5PY0wSwgvJU9jsdUNY.png)
![](https://remnote-user-data.s3.amazonaws.com/WdGtvaee2NXbjrUECAn5DOBhXGbXRdp1dLkPG-2IrVSwuup3_ao_bMXXHkqU2066UXWz_a3kUnBy35N9SrWR8irMHn6tWmyj-7MPQGNWYeqmFzF41gi6doGosN2-Pive.png)
到这里证明我们的这个原理是行得通的了。那么下面就用程序来实现这个过程
## 3.2. 使用Python读取数据库
### 3.2.1. 代码
```
#导入sqllite3模块
import sqlite3
# 1.硬盘上创建连接
con = sqlite3.connect('D:\MailMasterData\hengzhe19711121@163.com_1414\search.db')
# 获取cursor对象
cur = con.cursor()
# 执行sql创建表
sql = 'select * from Search_content'
try:
cur.execute(sql)
# 获取所有数据
person_all = cur.fetchall()
# print(person_all)
# 遍历
for p in person_all:
print(p)
except Exception as e:
print(e)
print('查询失败')
finally:
# 关闭游标
cur.close()
# 关闭连接
con.close()
```
- ![](https://remnote-user-data.s3.amazonaws.com/JB4V238rBcM4EKG_QvfzoLXc22m-3pmiAFLianWrh0WDeEq3oZKQK50vw8gpcDRNzGwrlyvWhj6pV_mVc5PcuXVYOpt9NHgtigGlfsKXpsVNOrkB5_-05GCiAz-uPAep.png)
# 4. 探究结果
## 4.1. 函数
### 4.1.1. 找到特定邮~箱的最新一条邮件
```
def sqlite3_get_last_data(db_path,sql): 找到特定邮箱最后一次的数据
# 导入sqllite3模块
import sqlite3
# 1.硬盘上创建连接
con = sqlite3.connect(db_path)
# 获取cursor对象
cur = con.cursor()
# 执行sql创建表
try:
cur.execute(sql)
# 获取所有数据
person_all = cur.fetchall()
last_data = person_all[-1]
# print(last_data)
# print("type(last_data):", type(last_data))
# print("last_data:", )
last_text = last_data
return last_text
except Exception as e:
print(e)
print('查询失败')
finally:
# 关闭游标
cur.close()
# 关闭连接
con.close()
email_path = 'hengzhe19711121@163.com'
db_path = 'D:\MailMasterData\{}_1414\search.db'.format(email_path)
sql = 'select * from Search_content'
```
![](https://remnote-user-data.s3.amazonaws.com/Ww0rMdaB47iALVtFWfWMJA8A0HwgJ0IrFqDWUMabGO1xYEqe-XvYBWirhsQTqGcovQ1TBrgWDrsA93xKOKiQ1UnFnKzgR32ZNqIR9ZWuWgsKBDaMoo7tiv9vKJHvnFVT.png)
### 4.1.2. 找到特定邮箱的最新一次验证码
![](https://remnote-user-data.s3.amazonaws.com/4hu7LDygkX0CFMYiv9r9s4CPRoeVBo215WXNEhP6zRdxFGgXyNvvnmVlnx627zShzCfmXUyWiuwnhGdA3G_Fy3rNDDked18dCq2IE5kjhoggvTbDcYmfLrXhixUHr2z6.png)
代码
```
def find_spacial_email_last_Verification_Code(email): #找到特定邮箱最后一次的验证码
def sqlite3_get_last_data(db_path, sql):
# 导入sqllite3模块
import sqlite3
# 1.硬盘上创建连接
con = sqlite3.connect(db_path)
# 获取cursor对象
cur = con.cursor()
# 执行sql创建表
try:
cur.execute(sql)
# 获取所有数据
person_all = cur.fetchall()
last_data = person_all[-1]
# print(last_data)
# print("type(last_data):", type(last_data))
# print("last_data:", )
last_text = last_data
return last_text
except Exception as e:
print(e)
print('查询失败')
finally:
# 关闭游标
cur.close()
# 关闭连接
con.close()
def find_continuous_data(string):# 查找字符串中连续的数字
import re
result = re.findall(r"\d{4,6}", string)
return result
def find_str_in_list_full_string(list_str, find_str):# 查找字符串列表中包含某一个字符的完整字符
for index, str in enumerate(list_str):
if find_str in str:
break
return str
import os
mailbox_rootpath = 'D:\MailMasterData'
email_name_list = os.listdir(mailbox_rootpath)
email_dir_name = find_str_in_list_full_string(email_name_list, email)
db_path = '{}\{}\search.db'.format(mailbox_rootpath,email_dir_name)
sql = 'select * from Search_content'
last_text = sqlite3_get_last_data(db_path, sql)
print("last_text:", last_text)
result = find_continuous_data(last_text)
if (len(result) == 1):
print('找到了验证码')
print(result)
pass
else:
from winsound import Beep
Beep(600, 1000)
email = 'zaluanwu92iek@163.com'
find_spacial_email_last_Verification_Code(email)
```
-
### 4.1.3. 通过命令行调用Python代码找到特定邮箱的最新的验证码
代码
```
def find_spacial_email_last_Verification_Code(email): #找到特定邮箱最后一次的验证码
def sqlite3_get_last_data(db_path, sql): #找到特定邮箱最后一次的数据
# 导入sqllite3模块
import sqlite3
# 1.硬盘上创建连接
con = sqlite3.connect(db_path)
# 获取cursor对象
cur = con.cursor()
# 执行sql创建表
try:
cur.execute(sql)
# 获取所有数据
person_all = cur.fetchall()
last_data = person_all[-1]
# print(last_data)
# print("type(last_data):", type(last_data))
# print("last_data:", )
last_text = last_data
return last_text
except Exception as e:
print(e)
print('查询失败')
finally:
# 关闭游标
cur.close()
# 关闭连接
con.close()
def find_continuous_data(string):# 查找字符串中连续的数字
import re
result = re.findall(r"\d{4,6}", string)
return result
def find_str_in_list_full_string(list_str, find_str):# 查找字符串列表中包含某一个字符的完整字符
for index, str in enumerate(list_str):
if find_str in str:
break
return str
import os
mailbox_rootpath = 'D:\MailMasterData'
email_name_list = os.listdir(mailbox_rootpath)
email_dir_name = find_str_in_list_full_string(email_name_list, email)
db_path = '{}\{}\search.db'.format(mailbox_rootpath,email_dir_name)
sql = 'select * from Search_content'
last_text = sqlite3_get_last_data(db_path, sql)
# print("last_text:", last_text)
result = find_continuous_data(last_text)
if (len(result) == 1):
print('找到了验证码')
print(result)
pass
else:
from winsound import Beep
Beep(600, 1000)
import os
import argparse
parser = argparse.ArgumentParser(description='命令行传入参数')
#type是要传入的参数的数据类型help是该参数的提示信息
parser.add_argument('--email', type=str, help='传入的邮箱')
args = parser.parse_args()
#获得传入的参数
print(args.email)
email = args.email
find_spacial_email_last_Verification_Code(email)
```
- python .\读取特定邮箱的数据库.py --email "hengzhe19711121@163.com"
![](https://remnote-user-data.s3.amazonaws.com/UEi27fvKqHHzWh38dUAWp3l49wOlUHzlMX4xyjDq_DJ7klV9HM7KHXrBc4cm-wZFNlwyT3NiJEnCPtu8YNeXEbzFm6bSR6uRLsicvoiZzoFQG5rEh52-sFvL_swUlPsj.png) 我真的爱发明 发表于 2022-12-28 22:52
这种方式是不是需要手机号获得对应的信息?
没有吧。就在邮箱设置里开启IMAP功能时要用手机确认一下来获取授权码。以后脚本用邮箱用户名、授权码登录。
(我以前只写过学校邮箱的脚本,学校邮箱可以直接拿用户名密码登录收发邮件,而网易QQ这些邮箱都是用授权码、不用密码。)
另外就是多一个ID字段要加……刚刚随便搜了一下,参考这两个帖子:
python邮件处理(1)-IMAP收取邮件_w.royee的博客-CSDN博客_imap python https://blog.csdn.net/naoyaolin0720/article/details/119851663
【2020可用】Python使用 imaplib imapclient连接网易邮箱提示 Unsafe Login. Please contact kefu@188.com for help 的解决办法_去山的那边看海啊的博客-CSDN博客 https://blog.csdn.net/jony_online/article/details/108638571 谢谢分享 {:1_919:}{:1_921:} 感谢分享 实用技术,感谢分享,收藏备用! 感谢分享了。我是觉得可能利用邮箱的IMAP协议读取的多一点?不过解析客户端多种思路多种手段了。 LightswornSnow 发表于 2022-12-28 22:34
感谢分享了。我是觉得可能利用邮箱的IMAP协议读取的多一点?不过解析客户端多种思路多种手段了。
这种方式是不是需要手机号获得对应的信息? 过来学习一下,不错。 我很赞同! 学习了 谢谢分享