MENU

【日常Py】利用SMTP批量验证邮箱真实性

July 5, 2019 • Read: 3978 • 技术杂谈

沉寂的一个月,经历了事情不少,心情也是起伏波动;希望早点结束。

a4ecdf536f89d1bb8741b4f126e22907.jpg

回归正题,前一段时间一朋友给我提了一需求,需要批量验证QQ是否开通邮箱;然而我的第一反应是:判断邮箱是否开通,往这个邮箱发一封邮件不就知道咯?,事实上可行的,但是效率上就低了。

查了一波资料,发现一个不错的方法,直接Socket,连接SMTP服务器,验证查询收件人效率贼高,之前我也没怎么了解过这方面的协议,不懂的可以先来普及一波。

SMTP协议:https://www.cnblogs.com/liaocheng/p/4243465.html
然后在我们的电脑上验证一波,Crtl+R输入CMD调出命令窗。

1、输入telnet mx1.qq.com 25 响应:1.png
2、输入helo qzone.work 响应:2.png
3、输入mail from:<admin@qzone.work> 响应:
3.png
4、最后输入rcpt to:<1538236552@qq.com> 响应
4.png

不断输入验证rcpt to:<1538236552@qq.com>即可验证邮箱真实性,返回状态码250,即表示收件人存在(邮箱已开通),如果返回550,收件人不存在,邮箱未开通。5.png

Ps:如果命令错了,这个不能撤销,只能重新输入。

OK,到这儿就基本明白了吧,不断输入RCPT 验证就行,但邮件收件人有个最大收件人限制,一个连接只能验证一部分,失效需要重连。

光说不练假把式,Python3 里面直接用socket也就可以批量查询,上代码:

代码运行效果图:
6.png

#!/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()
Last Modified: May 5, 2023