pythoncsvdnsdnspy

Match Domains to DNS Resolver Name - Python


I am still new to Python, and have been working on this for work, and a few side projects with it for automating my Plex Media Management tasks.

I am trying to write a python script that would allow me to take a set list of domains from a csv file, match them to their dns name: Example (Plex.tv using 'NS' would return jeremy.ns.cloudflare.com)

My main goal is to read in the list of domains from a csv

run my code to match those domains to a dns resolver name

write those to either a new CSV file, and then zip the two together, which is what I have in my code.

I am having a few problems along the way.

  1. Visual Code doesn't allow import dns.resolver (not a huge issue, but if you know the fix for that it would save me from having to run it from command line)
  2. Matching Domains to their DNS resolver is throwing the error "AttributeError: 'list' object has no attribute 'is_absolute'"
import csv
import socket
import dns.resolver
import os
from os.path import dirname, abspath

# Setting Variables
current_path = dirname(abspath(__file__))
domainFName = '{0}/domains.csv'.format(current_path)
outputFile = '{0}/output.csv'.format(current_path)
dnsList = '{0}/list2.csv'.format(current_path)
case_list = []
fields = ['Domains', 'DNS Resolvers']
caseList = []
dnsResolve = []

# Read in all domains from csv into list
with open(domainFName, 'r') as file:
    for line in csv.reader(file):
        case_list.append(line)

print(case_list)

# Match domains to the DNS Resolver Name
for domains in case_list:
    answer = dns.resolver.resolve(domains, 'NS')
    server = answer.target
    dnsResolve.append(server)

# Write the dns Resolver names into a new csv file
with open(dnsList,'w', newline="") as r:
    writers = csv.writer(r)
    writers.writerows(caseList)      

# Write the domains and dns resolvers to new output csv
with open(outputFile,'w', newline="") as f:
    writer = csv.writer(f)
    writer.writerow(fields)
    writer.writerow(zip(case_list,caseList))

exit()

Thanks for any help


Solution

  • After a discussion with a co-worker, I was able to resolve my issue, and just for the sake of it, if anyone wants to use this code for a similar need (we use it for DMARC), I will post the whole code:

    import dns.resolver 
    import csv
    import os
    from os.path import dirname, abspath
    
    
    # Setting Variables
    current_path = dirname(abspath(__file__))
    domainFName = '{0}/domains.csv'.format(current_path)
    outputFile = '{0}/output.csv'.format(current_path)
    dnsList = '{0}/dnslist.csv'.format(current_path)
    backupCSV = '{0}/backup-output.csv'.format(current_path)
    case_list = []
    dns_list = []
    fields = ['Domains', 'DNS Resolvers']
    csv_output = zip(case_list, dns_list)
    domainAmount = 0
    rd = 00
    dnresolve = 00
    part = 0
    percentL = []
    percents = [10,20,30,40,50,60,70,80,90,95,96,97,98,99]
    percentList = []
    floatingList = []
    floatPart = []
    x = 00
    keyAzure = 'azure'
    keyCSC = 'csc'
     
    
    while x < .99:
        x += .01
        floatingList.append(x)
    
    # THIS IS THE CODE FOR WRITING CSV FILES INTO LISTS - LABELED AS #1
    print("FILES MUST BE CSV, WILL RETURN AN ERROR IF NOT. LEAVE OFF .CSV")
    
    # Here we will gather the input of which csv file to use. If none are entered, it will use domains.csv
    print("Enter your output file name (if blank will use default):")
    UserFile = str(input("Enter your filename: ") or "domains")
    fullFile = UserFile + '.csv'
    domainFName = fullFile.format(current_path)
    # Here will will specify the output file name. If the file is not created, it will create it
    # If the user enters not data, the default will be used, output.csv
    print("Enter your output file name (if blank will use default):")
    UserOutput = str(input("Enter your filename: ") or "output")
    fullOutput = UserOutput + '.csv'
    outputFIle = fullOutput.format(current_path)
    
    
    # Read in all domains from csv into list
    with open(domainFName, 'r') as file:
        for line in csv.reader(file):
            case_list.append(line)
            domainAmount += 1
            
    print("Starting the resolver:")
    print("You have " + str(domainAmount) + " Domains to resolve:")
    # THIS IS THE END OF THE CODE FOR WRITING CSV FILES INTO LISTS - LABELED AS #1
    
    # THE CODE BELOW IS WORKING FOR FINDING THE DNS RESOLVERS - LABELED AS #2
    # Function for matching domains to DNS resolvers
    def dnsResolver (domain):
        try:
            answers = dns.resolver.resolve(domain, 'NS')
            for server in answers:
                dns_list.append(server.target)   
        except:
            dns_list.append("Did Not Resolve")  
           
    print("Now resolving domains to their DNS name:")
    print("This will take a few minutes. Check out the progress bar for your status:")
    print("I have resolved 0% Domains:")
    
    # This code is for finding the percentages for the total amount of domains to find progress status
    def percentageFinder(percent, whole):
        return (percent * whole) / 100
    
    def percentGetter(part, whole):
        return (100 * int(part)/int(whole))   
    
    for x in percents:
        percentList.append(int(percentageFinder(x,domainAmount)))
        percentL = percentList
    #End code for percentage finding
    
    for firstdomain in case_list:
        for domain in firstdomain:
            dnsResolver(domain)
            if dnsResolver != "Did Not Resolve":
                rd += 1
            else:
                dnresolve += 1
            # Using w+ to overwrite all Domain Names & 
            with open(dnsList,'w+', newline="") as r:
                writers = csv.writer(r)
                writers.writerows(dns_list)
            # This is used for showing the percentage of the matching you have done
            part += 1
            if part in percentL:
                total = int(percentGetter(part, domainAmount))
                print("I Have Resolved {}".format(total) + "%" + " Domains:")
            else:
                pass
    
            
            
    print("Resolving has completed. Statistics Below:")
    print("------------------------------------------")
    
    
    
    print("You had " + str(rd) + " domains that resolved.")
    print("You had " + str(dnresolve) + " domains that did NOT resolve")
    
    
    
    # THIS IS THE END OF THE WORKING CODE - LABELED AS #2     
       
    # Write the dns Resolver names into a new csv file
    print("Now writing your domains & their DNS Name to an Output File:")
    
    with open(outputFile,'w+', newline="\n") as f:
        writer = csv.writer(f, dialect='excel')
        writer.writerow(fields)
        for row in csv_output:
            writer.writerow(row)
    
    
    print("Writing a backup CSV File")
    
    # Using this to create a backup in case to contain all domains, and all resolvers
    # If someone runs the script with a small list of domains, still want to keep a 
    # running list of everything in case any questions arise.
    # This is done by using 'a' instead of 'w' or 'w+' done above.
    with open(backupCSV,'w', newline="") as f:
        writer = csv.writer(f, dialect='excel')
        writer.writerow(fields)
        for row in csv_output:
            writer.writerow(row)
    print("Your backup is now done processing. Exiting program")
    
    # Sort the files by keyword, in this case the domain being azure or csc
    for r in dns_list:
        if keyAzure in r:
            for x in keyAzure:
                FileName = x
                print(FileName)
    
    exit()