In this article we will see how to make a WHOIS request with Python.
A WHOIS request is made by querying a remote server by socketing on port 43 and sending the domain name as a byte stream followed by a carriage return.
We need a WHOIS server list in JSON or CSV format that contains the hostname of the server and the domain extension it manages.
To extract the domain extension from the FQDN we can install the module tldextract which also handles double extensions (like .co.uk
). Our JSON file containing the list of WHOIS servers will have the following structure for each entry:
{
"extension": ".it",
"server": "whois.nic.it",
"response": "AVAILABLE"
}
We define a first function to read the contents of this file as a list of dictionaries.
import socket
import json
import tldextract
def get_whois_server_list(list_path='./servers.json'):
with open(list_path, 'r') as f:
return json.load(f)
Now we have to find in this list of dictionaries the element whose key extension
corresponds to the extension that we will have to extract from the domain name. To search efficiently, we will use the filter()
function on the list.
def find_whois_server_for_domain(domain_name=None):
if domain_name is None:
return None
full_domain_url = f'https://{domain_name}'
domain_extension = tldextract.extract(full_domain_url)
full_extension = f'.{domain_extension.suffix}'
whois_server_list = get_whois_server_list()
whois_server_found = list(
filter(lambda server: server['extension'] == full_extension, whois_server_list))
whois_server = whois_server_found[0] if len(
whois_server_found) > 0 else None
return whois_server
Finally, we need to connect via socket to the server that manages the extension of the selected domain and return the response as output. This response will have to be constructed by reading from the returned data stream as the remote server sends it.
def whois_lookup(domain_name=None):
if domain_name is None:
return None
whois_server = find_whois_server_for_domain(domain_name)
if whois_server is None:
return None
query = f'{domain_name}\r\n'
server = whois_server['server']
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.connect((server, 43))
connection.send(query.encode())
response = ''
while len(response) < 10000:
chunk = connection.recv(100).decode()
if (chunk == ''):
break
response = response + chunk
return response
The response comes as a byte stream, so we need to convert it to a string if we want to represent it legibly on the shell. Usage example:
def main():
domain = input('Enter domain name:')
print(whois_lookup(domain))
if __name__ == '__main__':
main()