沉寂的一个月,经历了事情不少,心情也是起伏波动;希望早点结束。
回归正题,前一段时间一朋友给我提了一需求,需要批量验证QQ是否开通邮箱;然而我的第一反应是:判断邮箱是否开通,往这个邮箱发一封邮件不就知道咯?,事实上可行的,但是效率上就低了。
查了一波资料,发现一个不错的方法,直接Socket,连接SMTP服务器,验证查询收件人效率贼高,之前我也没怎么了解过这方面的协议,不懂的可以先来普及一波。
SMTP协议:https://www.cnblogs.com/liaocheng/p/4243465.html
然后在我们的电脑上验证一波,Crtl+R
输入CMD调出命令窗。
1、输入telnet mx1.qq.com 25
响应:
2、输入helo qzone.work
响应:
3、输入mail from:<admin@qzone.work>
响应:
4、最后输入rcpt to:<1538236552@qq.com>
响应
不断输入验证rcpt to:<1538236552@qq.com>
即可验证邮箱真实性,返回状态码250,即表示收件人存在(邮箱已开通),如果返回550,收件人不存在,邮箱未开通。
Ps:如果命令错了,这个不能撤销,只能重新输入。
OK,到这儿就基本明白了吧,不断输入RCPT 验证就行,但邮件收件人有个最大收件人限制,一个连接只能验证一部分,失效需要重连。
光说不练假把式,Python3 里面直接用socket也就可以批量查询,上代码:
代码运行效果图:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : Main.py
# @Author: MoMing
# @Date : 2019/7/5
# @Desc : 学习测试
from time import sleep
from socket import socket, AF_INET, SOCK_STREAM
def get_conn_init(): # SMTP服务器初始化
host = 'mx1.qq.com'
port = 25
bufsize = 1024
s = socket(AF_INET, SOCK_STREAM)
try:
s.connect((host, port))
except TimeoutError: # 链接超时
return False
s.recv(1024).decode('utf-8')
s.send('HELO qzone.work\r\nMAIL FROM:<admin@qzone.work>\r\n'.encode('utf-8'))
tmp = s.recv(bufsize).decode('utf-8')
msg = tmp.split('\r\n')
if len(msg) > 1 and msg[2][:3] == '250':
return s
else:
sleep(3)
return get_conn_init()
def check(mail_):
global conn
conn.send(('RCPT TO:<' + mail_ + '>\r\n').encode('utf-8'))
reback = (conn.recv(1024).decode('utf-8'))[:3]
if not conn:
print('STMP服务器连接失败,马上重试!')
conn = get_conn_init()
elif reback == '452': # 失效重连
conn.close()
conn = get_conn_init()
elif reback == '250':
return '已开通'
elif reback == '550':
return '未开通'
else:
return reback
if __name__ == '__main__':
conn = get_conn_init()
check_list = ['23123@qq.com', '236546123@qq.com', 'fdsdf@qq.com', 'njfd@qq.com', 'mfgg@qq.com',
'12345@qq.com'] # 待检测列表
for mail in check_list:
print(mail, check(mail))
else:
conn.close()