Получение IP от команды 'host', выполняемой внутри python - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть эта функция, чтобы показать мне первый IP-адрес домена:

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]

Но это показывает только первый IP. Я хотел бы показать только IP-адреса. Маркер не имеет «адреса», как показано ниже (представьте, что я ввел «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.']

Я хочу показать только ips, а не reddit.com has address и не один раз конец ip, mail is handled и т. Д.

Я пытался с

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

Но это не работает! Даже не вернул ничего полезного!

Я ожидаю массив с (в данном случае):

'151.101.65.140', '151.101.129.140', '151.101.193.140', '151.101.1.140'

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018

Смотрите, это показывает несколько хостов, как вам нужно. Ваш вывод может быть сгенерирован с использованием map функции

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']
0 голосов
/ 12 ноября 2018

Вы должны попробовать команду dig вместо хоста и применить правильное регулярное выражение 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

Примечания:

  • Параметр прогона может варьироваться в зависимости от того, какая у вас версия Python, это пример для Python 3.5: https://docs.python.org/3.5/library/subprocess.html
  • Вы должны адаптировать этот код к некоторым пограничным случаям.

EDIT

Как уже упоминалось в комментариях, вы можете удалить часть регулярного выражения, используя опцию + short в dig.

0 голосов
/ 12 ноября 2018

Попробуйте разделить строковые IP-адреса по их пробелам, используя .split(), а затем возьмите последний элемент этого [-1] и затем разделите последний элемент (который должен быть IP-адресом) в периоды .split('.'). Соедините строки, возвращенные из этого, используя ''.join(iterable), где итерируемое значение из .split('.'). Проверьте, является ли объединенная строка числовым значением, используя .isnumeric(), и если это True, напечатайте и верните последний элемент.

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

Плохая новость в том, что я не могу заставить results=str(process.read()) быть установленным на что-либо. В настоящее время он просто возвращает пустую строку, но, надеюсь, вам повезет больше: D

(Редактировать: как сказано в ваших комментариях, socket.getaddrinfo() работает с плавающими цветами. Не уверен в этом на Python 2.7, но здесь работает в 3.7.1)

(Edit2: вот ваш код в 3.7.1. Должен быть похож в 2.7)

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