python: correct method verify if email exists

Sam Rohn picture Sam Rohn · Nov 30, 2018 · Viewed 12.5k times · Source

I am trying to verify if an email actually exists by first resolving its dns, then check if the email is valid using the below code:

    email = [email protected]
    domain = email.split("@")[-1]
    records = dns.resolver.query(domain, 'MX')
    mxRecord = records[0].exchange
    mxRecord = str(mxRecord)
    server.connect(mxRecord)
    server.helo(host)
    server.mail('[email protected]')
    code, message = server.rcpt(str(email))
    server.quit()
    if code == 250:
        print('valid email', message) 
    else:
        print('invalid email', message)

This works few times, but when I send multiple request I get a message like:

"5.7.1 Service unavailable, Client host [122.166.xxx.xxx] blocked using Spamhaus. To request removal from this list see http://www.spamhaus.org/lookup.lasso (AS160312312) [BL2NAM02FT12312.eop-nam02.prod.protection.outlook.com]'"

I understand that they are trying to block my ip address as it thinks its spammy.

Here are my questions:

  • Is there a right way to do this type of email validation, without getting marked as spam? Is it getting marked as spam as I am running the code on my system and just giving a dummy value for email like

server.mail('[email protected]')

  • Is it possible to use some proxy to do this? My usecase require 100's of email addresses to be verified. I see some commercial api available for email validation, but it is not feasible for me at the moment.

Answer

Ali Najafi picture Ali Najafi · Aug 19, 2019

This method in dnslib is not suitable for bulk email validation. because smtp server blocks you if you send a lot of email validation request. then you should use proxy via pysocks library. You can also see this post on medium:

import socket
import socks # PySocks

from smtplib import SMTP

class SocksSMTP(SMTP):

def __init__(self,
        host='',
        port=0,
        local_hostname=None,
        timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
        source_address=None,
        proxy_type=None,
        proxy_addr=None,
        proxy_port=None,
        proxy_rdns=True,
        proxy_username=None,
        proxy_password=None,
        socket_options=None):

    self.proxy_type=proxy_type
    self.proxy_addr=proxy_addr
    self.proxy_port=proxy_port
    self.proxy_rdns=proxy_rdns
    self.proxy_username=proxy_username
    self.proxy_password=proxy_password
    self.socket_options=socket_options
    # if proxy_type is provided then change the socket to socksocket
    # else behave like a normal SMTP class.
    if self.proxy_type:
        self._get_socket = self.socks_get_socket

    super(SocksSMTP, self).__init__(host, port, local_hostname, timeout, source_address)

def socks_get_socket(self, host, port, timeout):
    if self.debuglevel>0:
        self._print_debug('connect: to', (host, port), self.source_address)
    return socks.create_connection((host, port),
            timeout=timeout,
            source_address=self.source_address,
            proxy_type=self.proxy_type,
            proxy_addr=self.proxy_addr,
            proxy_port=self.proxy_port,
            proxy_rdns=self.proxy_rdns,
            proxy_username=self.proxy_username,
            proxy_password=self.proxy_password,
            socket_options=self.socket_options)