Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: correct method verify if email exists

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.
like image 892
Sam Rohn Avatar asked Nov 30 '18 16:11

Sam Rohn


People also ask

Which method is used to check the validation of a email address?

Double opt-in method The most popular technique used by companies to test email validity is probably double opt-in.

How do I verify my flask email?

It's time to test out the app. Make sure that Flask is running on your terminal with flask run . Visit http://localhost:5000/ and enter your personal email address. Check your email to see an email from "[email protected]" and find the verification code provided by Twilio Verify.


3 Answers

As of 2021, the most updated python3 package I could find was py3-validate-email

Basic Usage:

from validate_email import validate_email
is_valid = validate_email(email_address='[email protected]', check_regex=True, check_mx=True, from_address='[email protected]', helo_host='my.host.name', smtp_timeout=10, dns_timeout=10, use_blacklist=True, debug=False)

Installation:

pip3 install py3-validate-email
like image 93
Pedro Lobito Avatar answered Sep 21 '22 19:09

Pedro Lobito


yes you will quite likely get marked as spam. If you want to avoid that you'll need to put in a bit of work fighting the anti-spam measures.

You could consider using a service like Real Email to do the validations. eg

import requests

api_key = "" // todo put your api key here
email_address = "[email protected]"
response = requests.get(
    "https://isitarealemail.com/api/email/validate",
    params = {'email': email_address},
    headers = {'Authorization': "Bearer " + api_key })

status = response.json()['status']
if status == "valid":
  print("email is valid")
elif status == "invalid":
  print("email is invalid")
else:
  print("email was unknown")
like image 26
Stephen Avatar answered Sep 20 '22 19:09

Stephen


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)
like image 21
Ali Najafi Avatar answered Sep 18 '22 19:09

Ali Najafi