-1

I have this function to show me the 1st ip of a domain:

def get_ip_address(url):
    command="host "+url
    process=os.popen(command)
    results=str(process.read()) 
    marker=results.find('has address')+12   
    print results[marker:].splitlines()[0]
    return results[marker:].splitlines()[0]

But this only shows me the first ip. I'd like to show only the ip's. The marker is for not having "has address" as shown below (imagine I input "reddit.com":

['151.101.65.140', 'reddit.com has address 151.101.129.140', 'reddit.com has address 151.101.193.140', 'reddit.com has address 151.101.1.140', 'reddit.com mail is handled by 1 aspmx.l.google.com.', 'reddit.com mail is handled by 10 aspmx2.googlemail.com.', 'reddit.com mail is handled by 10 aspmx3.googlemail.com.', 'reddit.com mail is handled by 5 alt1.aspmx.l.google.com.', 'reddit.com mail is handled by 5 alt2.aspmx.l.google.com.']

I want to show only the ips, not reddit.com has addressnor once the ip's end, mail is handledetc.

I tried with

def get_ip_address(url):
    command="host "+url
    process=os.popen(command)
    results=str(process.read()) 
    marker=results.find('has address')+12
    i=0
    arrayIps=[]
    while "has address" in results[marker:].splitlines()[i]:

        print results[marker:].splitlines()[i]
        arrayIps.append(results[marker:].splitlines()[i])
        print("array")
        print arrayIps[i]
        i=i+1
    return arrayIps

But it is not working! Not even returning anything useful!

What I am expecting is an array with (in this case):

'151.101.65.140', '151.101.129.140', '151.101.193.140', '151.101.1.140'
Louis Storming
  • 151
  • 1
  • 10
  • 2
    If you want to perform dns lookups in Python, why not using something like the [socket.getaddrinfo](https://docs.python.org/3/library/socket.html#socket.getaddrinfo) function in the Python standard library? – larsks Nov 12 '18 at 04:21
  • 1
    Wouldn't what you are suggesting, only show the first one (as I did?). I want to show all the ones that are possible! And I used this as I wanted to call the command. @larsks – Louis Storming Nov 12 '18 at 04:23
  • @LouisStorming It will show all the ones possible, just try it – Albin Paul Nov 12 '18 at 04:28
  • Rather than asking what it returns, just try it out. It will require less typing than was required to write that comment :). – larsks Nov 12 '18 at 04:30
  • it does not. I tried... @AlbinPaul – Louis Storming Nov 12 '18 at 04:35
  • `os.popen()` has documentation which clearly says **do not use.** You might want to review https://stackoverflow.com/a/51950538/874188 – tripleee Nov 12 '18 at 07:13

3 Answers3

2

See it shows multiple hosts as you required .Your output can be generated using a map function

In [132]: socket.getaddrinfo("reddit.com", 80, proto=socket.IPPROTO_TCP)
Out[132]: 
[(<AddressFamily.AF_INET: 2>,
  <SocketKind.SOCK_STREAM: 1>,
  6,
  '',
  ('151.101.65.140', 80)),
 (<AddressFamily.AF_INET: 2>,
  <SocketKind.SOCK_STREAM: 1>,
  6,
  '',
  ('151.101.1.140', 80)),
 (<AddressFamily.AF_INET: 2>,
  <SocketKind.SOCK_STREAM: 1>,
  6,
  '',
  ('151.101.129.140', 80)),
 (<AddressFamily.AF_INET: 2>,
  <SocketKind.SOCK_STREAM: 1>,
  6,
  '',
  ('151.101.193.140', 80))]


In [134]: list(map(lambda x:x[4][0],socket.getaddrinfo("reddit.com", 80, proto=socket.IPPROTO_TCP)))
Out[134]: ['151.101.129.140', '151.101.193.140', '151.101.65.140', '151.101.1.140']
Albin Paul
  • 3,330
  • 2
  • 14
  • 30
0

You should try the dig command instead of host and apply a proper regexp aswell:

from subprocess import run, PIPE

def get_answer(url):
    response = run(["dig", "+noall", "+answer", "+short","{url}".format(url=url)], stdout=PIPE, universal_newlines=True)
    return response.stdout

Notes:

EDIT

As mentioned in commentaries, you can rid off the regex part using +short option in dig.

-1

Try splitting the string IPs at their spaces using .split() and then taking the last item of it [-1] and then splitting the last item (which should be an IP address) at the periods .split('.'). Join the strings returned from that using ''.join(iterable) where iterable are the value from .split('.'). Check if the joined string is a numeric value using .isnumeric() and if that is True, print and return the last item.

def get_ip_address(url):
    command="host "+url
    process=os.popen(command)
    results=str(process.read())
    marker=results.find('has address')+12
    ip_list=[]
    for ip in results[marker:].splitlines()[0]:
        if ''.join(ip.split()[-1].split('.')).isnumeric():
            ip_list.append(ip.split()[-1])
    print ip_list
    return ip_list

The bad news is that I can't seem to get results=str(process.read()) to be set to anything. It currently just returns an empty string, but hopefully, you'll have more luck :D

(Edit: As said in your comments, socket.getaddrinfo() works with flying colours. Not sure of it on Python 2.7, but it works here in 3.7.1)

(Edit2: Here's your code in 3.7.1. Should be similar in 2.7)

import socket
ip_list = []
for info in socket.getaddrinfo('reddit.com', 80):
    ip_list.append(info[-1][0])
GeeTransit
  • 1,458
  • 9
  • 22