Is there a python-module that's doing the same stuff as nslookup does? I am planning to use nslookup on digging some information regarding the domain of a URL to be scrapped. I know I can use os.sys to call nslookup but I am just wondering if there is a python-module for this already. Thanks in advance!
9 Answers
I'm using the following code:
import socket
ip_list = []
ais = socket.getaddrinfo("www.yahoo.com",0,0,0,0)
for result in ais:
ip_list.append(result[-1][0])
ip_list = list(set(ip_list))
Or using a comprehension as:
ip_list = list({addr[-1][0] for addr in socket.getaddrinfo(name, 0, 0, 0, 0)})

- 47,830
- 31
- 106
- 135

- 739
- 5
- 6
-
Socket doesn't appear to work very well for nslookup, especially if there are multiple domains for all the hostnames. – Nathan McKaskle May 10 '19 at 15:14
-
1This works for me to get a list of IPs in a kubernetes statefulset – Mitchell Tracy Feb 07 '20 at 15:23
You need to use DNSPython
import dns.resolver
answers = dns.resolver.query('dnspython.org', 'MX')
for rdata in answers:
print 'Host', rdata.exchange, 'has preference', rdata.preference

- 3,958
- 2
- 22
- 30
-
-
dnspython is a utility to work with DNS, /etc/hosts is thus not used. For simple forward DNS lookups, it's better to use socket.gethostbyname() (fount on github of dnspython) – Rafal Jun 13 '20 at 07:18
the problem is that socket.gethostbyname() returns only one ip-address. nslookup returns as many as it has. I use:
import subprocess
process = subprocess.Popen(["nslookup", "www.google.com"], stdout=subprocess.PIPE)
output = process.communicate()[0].split('\n')
ip_arr = []
for data in output:
if 'Address' in data:
ip_arr.append(data.replace('Address: ',''))
ip_arr.pop(0)
print ip_arr
it will print:
['54.230.228.101', '54.230.228.6', '54.230.228.37', '54.230.228.80', '54.230.228.41', '54.230.228.114', '54.230.228.54', '54.230.228.23']

- 521
- 6
- 8
You should use socket library http://docs.python.org/2/library/socket.html
System function call is not a good practice in this case.

- 406
- 4
- 9
Note that socket.getfqdn()
can return the full-qualified name of a hostname. See: http://docs.python.org/2/library/socket.html?highlight=socket.getaddrinfo#socket.getfqdn
For example:
python -c 'import socket; print(socket.gethostname()); print(socket.getfqdn());'
myserver
myserver.mydomain.local
But the result depends the /etc/hosts
configuration. If you have:
$ cat /etc/hosts
127.0.0.1 myserver localhost.localdomain localhost
The result of socket.getfqdn()
will be:
python -c 'import socket; print(socket.getfqdn());'
localhost.localdomain
Oooops! To solve that, the only solution I know is to change the /etc/hosts
as follow:
$ cat /etc/hosts
127.0.0.1 myserver myserver.mydomain.local localhost.localdomain localhost
Hope it helps!

- 21,958
- 6
- 58
- 103
-
While true and thorough, this looks up the local systems's hostname/fqdn. The OP asked how to lookup external dns names for site scraping. Still +1 for the info. – VooDooNOFX Jun 03 '14 at 21:34
-
When I get FQDN's I get maybe half the servers with full FQDNs and the rest are just hostname. nothing. Why? Nslookup shows the FQDN on those nothing servers. – Nathan McKaskle May 08 '19 at 19:41
-
@NathanMcKaskle, take a look at your `/etc/hosts`: you may find the answer yourself. – Laurent LAPORTE May 09 '19 at 07:12
-
@LaurentLAPORTE we have multiple dns domains and thousands of servers in different domains, I'm trying to get the fqdn from a hostname, it's all coming back with just "hostname." My hosts looks like 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 I dunno what's going on. – Nathan McKaskle May 10 '19 at 19:58
I needed to track down A records in AWS Route 53 using CNames. AKA messaging.myCompany.com
to moreSpecificMessaging.myCompanyInternal.com
I also use Socket, but another rather hidden method.
import socket
addr1 = socket.gethostbyname_ex('google.com')
print(addr1)
https://docs.python.org/3/library/socket.html#socket.gethostbyname_ex

- 71
- 1
- 3
-
We can also call `socket.gethostbyname('google.com')`. https://docs.python.org/2/library/socket.html#socket.gethostbyname – HarlemSquirrel Aug 20 '18 at 15:17
-
gethostbyname() does not support IPv6 name resolution, and getaddrinfo() should be used instead for IPv4/v6 dual stack support. – Christoph Lösch Jul 21 '19 at 01:22
Previous answers are correct but here is what I would use socket, it "provides access to the BSD socket interface. It is available on all modern Unix systems, Windows, MacOS, and probably additional platforms."
import socket
distinct_ips = []
# 0,0,0,0 is for (family, type, proto, canonname, sockaddr)
#change some_site.com to whatever your are looking up of course
socket_info = socket.getaddrinfo("some_site.com",0,0,0,0)
for result in socket_info:
ns_ip = result[4][0]
if distinct_ips.count(ns_ip)==0:
distinct_ips.append(ns_ip)
print(ns_ip)

- 21,260
- 6
- 105
- 81
I'm using the following code:
import socket
addr1 = socket.gethostbyname('google.com')
addr2 = socket.gethostbyname('yahoo.com')
print(addr1, addr2)

- 111
- 1
- 5
-
1gethostbyname() does not support IPv6 name resolution, and getaddrinfo() should be used instead for IPv4/v6 dual stack support. – Christoph Lösch Jul 21 '19 at 01:22
$ sudo apt install python-dns
$ python
>>> import DNS
>>> d = DNS.DnsRequest(server="1.1.1.1", timeout=1)
>>> r = d.req(name="stackoverflow.com", qtype="A")
>>> [i['data'] for i in r.answers]
['151.101.129.69', '151.101.193.69', '151.101.1.69', '151.101.65.69']
Further details like ttl can also be accessed, plus this approach has the advantage of letting you specify which nameserver to use, instead of just using your system's default.

- 1,469
- 1
- 17
- 18