Imagine needing to quickly check who owns a domain, when it expires, or other registration details. Whether you’re a business assessing domain availability or just curious about website ownership, this information is more accessible than you might think. With the right tools, anyone can pull detailed domain data directly from their computer.
Today, I’ll show you how to use Python to build a simple yet powerful application that retrieves domain registration information. We’ll create an intuitive graphical user interface (GUI) using tkinter, Pyperclip, and python-whois libraries. By the end of this tutorial, you’ll be able to input any domain name and instantly view its registration details.
Let’s get started!
Table of Contents
- Necessary Libraries
- Imports
- Functions for Extracting Domain Data
- Creating the Main Window
- Creating Menu Bar
- Domain Entry
- Creating Check and Clear Buttons
- Result Text Widget
- Creating the History Widget
- Main Event Loop
- Example
- Full Code
Necessary Libraries
First, make sure to install these libraries using the terminal or your command prompt for the code to function properly:
$ pip install tk
$ pip install pyperclip
$ pip install python-whois
Imports
We want our program to be user-friendly. To achieve this, we import the tkinter
library as tk
to create a graphical user interface. From this library, we import scrolledtext
for a text widget with a scrollbar, messagebox
for using message boxes, and Menu
for creating menus.
We also import pyperclip
to copy texts via the clipboard, and whois
from the whois
library to query WHOIS information of domains.
import tkinter as tk
from tkinter import scrolledtext, messagebox, Menu
import pyperclip
from whois import whois
Functions for Extracting Domain Data
After importing the necessary libraries and modules, it’s time to define our functions – the heart of our code:
is_registered Function
The objective of this function is to check if a domain is registered by querying its WHOIS information. If the query is successful, it returns True
along with the WHOIS data. If it encounters an error during the process, it returns False
and an error message indicating the issue with the WHOIS query.
def is_registered(domain_name):
"""
Check if the domain name is registered by querying WHOIS data.
"""
try:
w = whois(domain_name)
return True, w
except Exception as e:
return False, f"Error querying WHOIS: {e}"
check_domain Function
This one first grabs the domain name entered in the entry widget, removing any extra spaces with entry.get().strip()
. If the entry is empty, it prompts the user to enter a domain name with an error message. Once the domain name is provided, the function checks if it’s registered using the is_registered()
function. The result of this check (is_reg
) and the WHOIS data (result
) are stored for later use.
Next, it updates the history widget to show the search history and temporarily enables it to add the new domain search. Once updated, it disables the widget to prevent changes.
Based on the is_reg
status, the function prepares an output_text
. If the domain is registered (is_reg
is True
), output_text
includes detailed WHOIS information. If not, it indicates the domain isn’t registered and shows an error message.
Finally, the function makes the result_text
widget editable, clears any previous text, inserts the output_text
, and then disables editing to secure the displayed information.
def check_domain():
domain_name = entry.get().strip()
if not domain_name:
messagebox.showerror("Error", "Please enter a domain name.")
return
is_reg, result = is_registered(domain_name)
# Enabling the history widget to update it
history.config(state=tk.NORMAL)
history.insert(tk.END, f"{domain_name}\n") # Log the domain checked
history.config(state=tk.DISABLED) # Disabling the history widget to prevent editing
if is_reg:
output_text = (
f"Domain registrar: {result.registrar}\n"
f"WHOIS server: {result.whois_server}\n"
f"Domain creation date: {result.creation_date}\n"
f"Expiration date: {result.expiration_date}\n\n"
f"{result}\n"
)
else:
output_text = f"{domain_name} is not registered.\n{result}"
result_text.config(state=tk.NORMAL)
result_text.delete('1.0', tk.END)
result_text.insert(tk.END, output_text)
result_text.config(state=tk.DISABLED)
clear_output Function
def clear_output():
entry.delete(0, tk.END)
result_text.config(state=tk.NORMAL)
result_text.delete('1.0', tk.END)
result_text.config(state=tk.DISABLED)
The clear_output()
function clears all content from the entry widget where the user inputs the domain name.
Next, it makes the result_text
widget editable by setting its state to Normal. It then deletes any existing text in the result_text
widget. Finally, it disables the result_text
widget to prevent any further editing.
copy_to_clipboard Function
def copy_to_clipboard():
if not result_text.compare("end-1c", "==", "1.0"):
pyperclip.copy(result_text.get("1.0", tk.END))
Once triggered, this function checks whether the result_text
widget is empty by comparing the end of its text to the beginning. If the widget contains text, it uses the pyperclip.copy
method to copy this text to the clipboard.
Creating the Main Window
# Setting up the main window
root = tk.Tk()
root.title("Domain WHOIS Checker - The Pycodes")
root.geometry("700x500")
In this part, we create the main window, set its title, and define its geometry.
Creating Menu Bar
For this step, we start by creating a menu bar and attaching it to our main window using root.config(menu=menubar)
. We then initialize a file_menu
with Menu(menubar, tearoff=0)
to prevent the menu from being separated from the window. We add three commands to the file_menu
: “Copy“, which triggers the copy_to_clipboard()
function; “Clear“, which activates the clear_output()
function; and “Exit“, which executes root.quit()
to close the main window.
Finally, we attach this file_menu
to the menubar under the label “File“.
# Menu Bar
menubar = Menu(root)
root.config(menu=menubar)
file_menu = Menu(menubar, tearoff=0)
file_menu.add_command(label="Copy", command=copy_to_clipboard)
file_menu.add_command(label="Clear", command=clear_output)
file_menu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=file_menu)
Domain Entry
Here, we start by creating a label that asks the user to enter a domain name and place it in the first column of the main window using the grid layout. Next to it, we create an entry widget where the user can input the domain name, aligning it next to the label in the grid.
# Domain entry
entry_label = tk.Label(root, text="Enter domain name:")
entry_label.grid(row=0, column=0, padx=10, pady=10, sticky='w')
entry = tk.Entry(root, width=50)
entry.grid(row=0, column=1, padx=10, pady=10, sticky='we')
Creating Check and Clear Buttons
In this section, we begin by creating a button labeled “Check Domain” that calls the check_domain()
function, and we place it on the main window using the grid layout at row 1, column 1. Then, next to it, we create another button labeled “Clear” that calls the clear_output()
function. We place this button on the main window using the grid layout at row 1, column 0, similar to the previous one.
# Check and clear buttons
check_button = tk.Button(root, text="Check Domain", command=check_domain)
check_button.grid(row=1, column=1, padx=10, pady=5, sticky='e')
clear_button = tk.Button(root, text="Clear", command=clear_output)
clear_button.grid(row=1, column=0, padx=10, pady=5, sticky='w')
Result Text Widget
Following that, we create the result_text
widget using scrolledtext.ScrolledText
, which is designed to display the WHOIS information and includes a scroll feature. We set its height to accommodate 10 lines. We then place it on the main window using the grid layout, specifying it to occupy row 2 and start at column 0, spanning across two columns. We also add padding on the x and y axes and ensure it stretches to fill the space in all directions (north, south, east, west).
# Result display area
result_text = scrolledtext.ScrolledText(root, height=10)
result_text.grid(row=2, column=0, columnspan=2, padx=10, pady=10, sticky='nsew')
Creating the History Widget
Now, we create a label titled “Search History:” and position it in the third row and zeroth column of the grid, adding padding for spacing. Below this label, we place a scrollable text widget that spans two columns. This widget displays the domain names we search and adapts its size to fill the space, adhering to the grid layout using the specified padding and sticky options.
# History Panel
history_label = tk.Label(root, text="Search History:")
history_label.grid(row=3, column=0, padx=10, pady=10, sticky='w')
history = scrolledtext.ScrolledText(root, height=5, state='disabled')
history.grid(row=4, column=0, columnspan=2, padx=10, pady=10, sticky='nsew')
Main Event Loop
Lastly, this part of the code kicks off the application and keeps the main window running smoothly, responding to user actions until someone decides to close it.
root.mainloop()
Example
I have run this code on Windows as shown below:
And also on Linux system:
Full Code
import tkinter as tk
from tkinter import scrolledtext, messagebox, Menu
import pyperclip
from whois import whois
def is_registered(domain_name):
"""
Check if the domain name is registered by querying WHOIS data.
"""
try:
w = whois(domain_name)
return True, w
except Exception as e:
return False, f"Error querying WHOIS: {e}"
def check_domain():
domain_name = entry.get().strip()
if not domain_name:
messagebox.showerror("Error", "Please enter a domain name.")
return
is_reg, result = is_registered(domain_name)
# Enabling the history widget to update it
history.config(state=tk.NORMAL)
history.insert(tk.END, f"{domain_name}\n") # Log the domain checked
history.config(state=tk.DISABLED) # Disabling the history widget to prevent editing
if is_reg:
output_text = (
f"Domain registrar: {result.registrar}\n"
f"WHOIS server: {result.whois_server}\n"
f"Domain creation date: {result.creation_date}\n"
f"Expiration date: {result.expiration_date}\n\n"
f"{result}\n"
)
else:
output_text = f"{domain_name} is not registered.\n{result}"
result_text.config(state=tk.NORMAL)
result_text.delete('1.0', tk.END)
result_text.insert(tk.END, output_text)
result_text.config(state=tk.DISABLED)
def clear_output():
entry.delete(0, tk.END)
result_text.config(state=tk.NORMAL)
result_text.delete('1.0', tk.END)
result_text.config(state=tk.DISABLED)
def copy_to_clipboard():
if not result_text.compare("end-1c", "==", "1.0"):
pyperclip.copy(result_text.get("1.0", tk.END))
# Setting up the main window
root = tk.Tk()
root.title("Domain WHOIS Checker - The Pycodes")
root.geometry("700x500")
# Menu Bar
menubar = Menu(root)
root.config(menu=menubar)
file_menu = Menu(menubar, tearoff=0)
file_menu.add_command(label="Copy", command=copy_to_clipboard)
file_menu.add_command(label="Clear", command=clear_output)
file_menu.add_command(label="Exit", command=root.quit)
menubar.add_cascade(label="File", menu=file_menu)
# Domain entry
entry_label = tk.Label(root, text="Enter domain name:")
entry_label.grid(row=0, column=0, padx=10, pady=10, sticky='w')
entry = tk.Entry(root, width=50)
entry.grid(row=0, column=1, padx=10, pady=10, sticky='we')
# Check and clear buttons
check_button = tk.Button(root, text="Check Domain", command=check_domain)
check_button.grid(row=1, column=1, padx=10, pady=5, sticky='e')
clear_button = tk.Button(root, text="Clear", command=clear_output)
clear_button.grid(row=1, column=0, padx=10, pady=5, sticky='w')
# Result display area
result_text = scrolledtext.ScrolledText(root, height=10)
result_text.grid(row=2, column=0, columnspan=2, padx=10, pady=10, sticky='nsew')
# History Panel
history_label = tk.Label(root, text="Search History:")
history_label.grid(row=3, column=0, padx=10, pady=10, sticky='w')
history = scrolledtext.ScrolledText(root, height=5, state='disabled')
history.grid(row=4, column=0, columnspan=2, padx=10, pady=10, sticky='nsew')
root.mainloop()
Happy Coding!
Hello,
Very helpful thank you…
Most welcome.
Hello
I just wanted to say thank you for sharing this helpful content, all the scripts work properly.
Thanks!
Mani J
Most welcome Sir, We are glad that you find them helpful.
Thank you!