Bulk MX record lookup via Python

In a previous post, I discussed a CMD script that allows checking DNS settings in bulk. The following script serves a similar purpose. It retrieves the domains to be checked from the input file “domains.txt” and stores the resolved MX records in the “mx_results.txt” file.

To facilitate DNS queries, the script imports the essential “dns.resolver” module from the dns package. This module is responsible for handling DNS resolution. To install the required package, you can use the following commands (Ubuntu Linux):

$ sudo apt install python3-pip
$ pip install dnspython

Below you find the Python script with comments explaining each section in more detail:

# Import the required module for DNS resolution
import dns.resolver

# Open the file containing the Domains
with open('domains.txt', 'r') as domain_file:
    # Read all lines from the file and store them in the 'domains' list
    domains = domain_file.readlines()

# Open a new file to write the MX records
with open('mx_results.txt', 'a', encoding='utf-8', buffering=1) as output_file:

    # Iterate through each domain in the 'domains' list
    for domain in domains:
        try:
            # Try to resolve the MX records for the current domain using the 'dns.resolver.resolve()' method
            # The 'strip()' method removes any leading or trailing whitespace characters from the domain
            answers = dns.resolver.resolve(domain.strip(), 'MX')

            # Extract the mail exchange server names from the 'answers' and store them in the 'mx_records' list
            # 'rdata.exchange' gives the mail exchange server name from the DNS response
            mx_records = [str(rdata.exchange) for rdata in answers]

        # Exceptions if there is an error:    
        except dns.resolver.NoAnswer:
            mx_records = ['Error: NoAnswer'] # no answer for the MX query
        except dns.resolver.NXDOMAIN:
            mx_records = ['Error: NXDOMAIN'] # domain does not exist
        except dns.resolver.NoNameservers:
            mx_records = ['Error: NoNameservers'] # there are no nameservers for the domain
        except dns.resolver.Timeout:
            mx_records = ['Error: Timeout'] # the DNS query times out
        except dns.resolver.NoRootSOA:
            mx_records = ['Error: NoRootSOA'] # there is no root SOA (Start of Authority) record
        except dns.exception.SyntaxError:
            mx_records = ['Error: SyntaxError'] # there is a syntax error in the DNS query
        except dns.resolver.NoMetaqueries:
            mx_records = ['Error: NoMetaqueries'] # metaqueries are not supported

        # Print the MX records or error messages to the console
        print(mx_records)

        # Write the MX records or error messages to the "output.txt" file followed by a newline character
        output_file.write(str(mx_records) + '\n')

Testing the script for the domain “gmail.com” will produce the following outputs:

Python MX terminal output
The MX records for each checked domain will be output on a new line enclosed in square brackets.
Python MX file output
The file output is similar to the terminal above; the results of each checked domain will be output to a new line.
asterix Written by:

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *