You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.7 KiB
Python
100 lines
3.7 KiB
Python
#!/usr/bin/env python2
|
|
|
|
import argparse, pythonwhois, json, datetime
|
|
from collections import OrderedDict
|
|
|
|
parser = argparse.ArgumentParser(description="Retrieves and parses WHOIS data for a domain name.")
|
|
parser.add_argument("-r", "--raw", action="store_true", help="Outputs raw WHOIS data and doesn't attempt to parse it. Segments are separated by a double-dash (--).")
|
|
parser.add_argument("-j", "--json", action="store_true", help="Outputs structured WHOIS data in JSON format, according to the pythonwhois API.")
|
|
parser.add_argument("-f", "--file", action="store", help="Loads and parses raw double-dash-delimited WHOIS data from a specified file, instead of contacting a WHOIS server.", default=None)
|
|
parser.add_argument("domain", nargs=1)
|
|
args = parser.parse_args()
|
|
|
|
def json_fallback(obj):
|
|
if isinstance(obj, datetime.datetime):
|
|
return obj.isoformat()
|
|
else:
|
|
return obj
|
|
|
|
if args.file is None:
|
|
data = pythonwhois.net.get_whois_raw(args.domain[0])
|
|
else:
|
|
with open(args.file, "r") as f:
|
|
data = f.read().split("\n--\n")
|
|
|
|
if args.raw == True:
|
|
print "\n--\n".join(data)
|
|
else:
|
|
parsed = pythonwhois.parse.parse_raw_whois(data, normalized=True)
|
|
|
|
if args.json == True:
|
|
print json.dumps(parsed, default=json_fallback)
|
|
else:
|
|
data_map = OrderedDict({})
|
|
|
|
# This defines the fields shown in the output
|
|
data_map["id"] = ("Domain ID", 1)
|
|
data_map["status"] = ("Status", 1)
|
|
data_map["registrar"] = ("Registrar", 1)
|
|
data_map["creation_date"] = ("Registration date", 1)
|
|
data_map["expiration_date"] = ("Expiration date", 1)
|
|
data_map["updated_date"] = ("Last update", 1)
|
|
data_map["nameservers"] = ("Name server", "+")
|
|
data_map["emails"] = ("E-mail address", "+")
|
|
|
|
widest_label = 0
|
|
for key, value in data_map.iteritems():
|
|
if len(value[0]) > widest_label:
|
|
widest_label = len(value[0])
|
|
|
|
for key, value in data_map.iteritems():
|
|
if key in parsed and parsed[key] is not None:
|
|
label = value[0] + (" " * (widest_label - len(value[0]))) + " :"
|
|
if value[1] == 1:
|
|
print "%s %s" % (label, parsed[key][0])
|
|
elif value[1] == "+":
|
|
for item in parsed[key]:
|
|
print "%s %s" % (label, item)
|
|
|
|
if parsed["contacts"] is not None:
|
|
# This defines the contacts shown in the output
|
|
contacts_map = OrderedDict({})
|
|
contacts_map["registrant"] ="Registrant"
|
|
contacts_map["tech"] = "Technical Contact"
|
|
contacts_map["admin"] = "Administrative Contact"
|
|
contacts_map["billing"] = "Billing Contact"
|
|
|
|
# This defines the contact data shown in the output
|
|
data_map = OrderedDict({})
|
|
data_map["handle"] ="NIC handle"
|
|
data_map["name"] ="Name"
|
|
data_map["organization"] = "Organization"
|
|
data_map["street"] = "Street address"
|
|
data_map["postalcode"] = "Postal code"
|
|
data_map["city"] = "City"
|
|
data_map["state"] = "State / Province"
|
|
data_map["country"] = "Country"
|
|
data_map["email"] = "E-mail address"
|
|
data_map["phone"] = "Phone number"
|
|
data_map["fax"] = "Fax number"
|
|
data_map["changedate"] = "Last changed"
|
|
|
|
for contact in contacts_map:
|
|
if parsed["contacts"][contact] is not None:
|
|
contact_data = parsed["contacts"][contact]
|
|
|
|
print "\n" + contacts_map[contact]
|
|
|
|
for key, value in data_map.iteritems():
|
|
if len(value) > widest_label:
|
|
widest_label = len(value)
|
|
|
|
for key, value in data_map.iteritems():
|
|
if key in contact_data and contact_data[key] is not None:
|
|
label = " " + value + (" " * (widest_label - len(value))) + " :"
|
|
actual_data = str(contact_data[key])
|
|
if "\n" in actual_data: # Indent multi-line values properly
|
|
lines = actual_data.split("\n")
|
|
actual_data = "\n".join([lines[0]] + [(" " * (widest_label + 7)) + line for line in lines[1:]])
|
|
print "%s %s" % (label, actual_data)
|