Поиск локальных IP-адресов с использованием Python's stdlib - PullRequest
480 голосов
/ 03 октября 2008

Как найти локальные IP-адреса (например, 192.168.x.x или 10.0.x.x) на платформе Python независимо и с использованием только стандартной библиотеки?

Ответы [ 43 ]

5 голосов
/ 12 июня 2012

Этот ответ - моя личная попытка решить проблему получения IP-адреса локальной сети, поскольку socket.gethostbyname(socket.gethostname()) также вернул 127.0.0.1. Этот метод не требует подключения к Интернету только через локальную сеть. Код для Python 3.x, но может быть легко преобразован для 2.x. Использование UDP Broadcast:

import select
import socket
import threading
from queue import Queue, Empty

def get_local_ip():
        def udp_listening_server():
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.bind(('<broadcast>', 8888))
            s.setblocking(0)
            while True:
                result = select.select([s],[],[])
                msg, address = result[0][0].recvfrom(1024)
                msg = str(msg, 'UTF-8')
                if msg == 'What is my LAN IP address?':
                    break
            queue.put(address)

        queue = Queue()
        thread = threading.Thread(target=udp_listening_server)
        thread.queue = queue
        thread.start()
        s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        waiting = True
        while waiting:
            s2.sendto(bytes('What is my LAN IP address?', 'UTF-8'), ('<broadcast>', 8888))
            try:
                address = queue.get(False)
            except Empty:
                pass
            else:
                waiting = False
        return address[0]

if __name__ == '__main__':
    print(get_local_ip())
4 голосов
/ 23 июня 2011

127.0.1.1 - это ваш реальный IP-адрес. Вообще говоря, компьютер может иметь любое количество IP-адресов. Вы можете отфильтровать их для частных сетей - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 и 192.168.0.0/16.

.

Однако нет кроссплатформенного способа получить все IP-адреса. В Linux вы можете использовать SIOCGIFCONF ioctl.

4 голосов
/ 30 апреля 2012

Небольшое уточнение версии команд, которая использует команду IP и возвращает адреса IPv4 и IPv6:

import commands,re,socket

#A generator that returns stripped lines of output from "ip address show"
iplines=(line.strip() for line in commands.getoutput("ip address show").split('\n'))

#Turn that into a list of IPv4 and IPv6 address/mask strings
addresses1=reduce(lambda a,v:a+v,(re.findall(r"inet ([\d.]+/\d+)",line)+re.findall(r"inet6 ([\:\da-f]+/\d+)",line) for line in iplines))
#addresses1 now looks like ['127.0.0.1/8', '::1/128', '10.160.114.60/23', 'fe80::1031:3fff:fe00:6dce/64']

#Get a list of IPv4 addresses as (IPstring,subnetsize) tuples
ipv4s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if '.' in addr)]
#ipv4s now looks like [('127.0.0.1', 8), ('10.160.114.60', 23)]

#Get IPv6 addresses
ipv6s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if ':' in addr)]
4 голосов
/ 29 ноября 2013

Ну, вы можете использовать команду "ip route" в GNU / Linux, чтобы узнать ваш текущий IP-адрес.

Показывает IP-адрес, предоставленный интерфейсу сервером DHCP, работающим на маршрутизаторе / модеме. Обычно «192.168.1.1/24» - это IP-адрес для локальной сети, где «24» означает диапазон возможных IP-адресов, заданных сервером DHCP в пределах диапазона маски.

Вот пример: обратите внимание, что PyNotify является лишь дополнением, чтобы понять мою точку зрения и не требуется вообще

#! /usr/bin/env python

import sys , pynotify

if sys.version_info[1] != 7:
   raise RuntimeError('Python 2.7 And Above Only')       

from subprocess import check_output # Available on Python 2.7+ | N/A 

IP = check_output(['ip', 'route'])
Split_Result = IP.split()

# print Split_Result[2] # Remove "#" to enable

pynotify.init("image")
notify = pynotify.Notification("Ip", "Server Running At:" + Split_Result[2] , "/home/User/wireless.png")    
notify.show()    

Преимущество этого в том, что вам не нужно указывать сетевой интерфейс. Это очень полезно при работе с сервером сокетов

Вы можете установить PyNotify, используя easy_install или даже Pip:

easy_install py-notify

или

pip install py-notify

или внутри скрипта / интерпретатора Python

from pip import main

main(['install', 'py-notify'])
3 голосов
/ 28 декабря 2017
import netifaces as ni 

ni.ifaddresses('eth0')
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip)

Это вернет вам IP-адрес в системе Ubuntu, а также MacOS. Вывод будет IP-адрес системы, как мой IP: 192.168.1.10.

3 голосов
/ 11 июня 2014

netifaces доступны через pip и easy_install. (Я знаю, это не в базе, но это может стоить установки.)

netifaces имеет некоторые странности на разных платформах:

  • Интерфейс localhost / loop-back не всегда может быть включен (Cygwin).
  • Адреса перечислены для каждого протокола (например, IPv4, IPv6), а протоколы для каждого интерфейса. В некоторых системах (Linux) каждая пара протокол-интерфейс имеет свой собственный связанный интерфейс (используя нотацию имя_интерфейса: n), в то время как в других системах (Windows) один интерфейс будет иметь список адресов для каждого протокола. В обоих случаях есть список протоколов, но он может содержать только один элемент.

Вот код netifaces для игры:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
# Note: Can't filter for 'lo' here because Windows lacks it.
ifaces = netifaces.interfaces()

# Get all addresses (of all kinds) for each interface
if_addrs = [netifaces.ifaddresses(iface) for iface in ifaces]

# Filter for the desired address type
if_inet_addrs = [addr[PROTO] for addr in if_addrs if PROTO in addr]

iface_addrs = [s['addr'] for a in if_inet_addrs for s in a if 'addr' in s]
# Can filter for '127.0.0.1' here.

Приведенный выше код не отображает адрес обратно на имя его интерфейса (полезно для генерации правил ebtables / iptables на лету). Итак, вот версия, которая хранит вышеуказанную информацию с именем интерфейса в кортеже:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
ifaces = netifaces.interfaces()

# Get addresses for each interface
if_addrs = [(netifaces.ifaddresses(iface), iface) for iface in ifaces]

# Filter for only IPv4 addresses
if_inet_addrs = [(tup[0][PROTO], tup[1]) for tup in if_addrs if PROTO in tup[0]]

iface_addrs = [(s['addr'], tup[1]) for tup in if_inet_addrs for s in tup[0] if 'addr' in s]

И, нет, я не влюблен в списки. Так работает мой мозг в наши дни.

Следующий фрагмент напечатает все это:

from __future__ import print_function  # For 2.x folks
from pprint import pprint as pp

print('\nifaces = ', end='')
pp(ifaces)

print('\nif_addrs = ', end='')
pp(if_addrs)

print('\nif_inet_addrs = ', end='')
pp(if_inet_addrs)

print('\niface_addrs = ', end='')
pp(iface_addrs)

Наслаждайтесь!

3 голосов
/ 14 марта 2018

Если вы ищете IPV4-адрес, отличный от вашего локального IP-адреса 127.0.0.1, вот вам пример кода Python:

import subprocess
address = subprocess.check_output(['hostname', '-s', '-I'])
address = address.decode('utf-8') 
address=address[:-1]

Который также можно записать в одну строку:

address = subprocess.check_output(['hostname', '-s', '-I']).decode('utf-8')[:-1]

Даже если вы введете localhost в /etc/hostname, код все равно даст ваш локальный IP-адрес.

3 голосов
/ 31 августа 2013

Примечание: это не стандартная библиотека, а довольно простая.

$ pip install pif

from pif import get_public_ip
get_public_ip()
3 голосов
/ 03 июня 2016

Чтобы получить IP-адрес, вы можете использовать команду оболочки непосредственно в python :

import socket, subprocess

def getIpAndHostname():
    hostname =  socket.gethostname()

    shell_cmd = "ifconfig | awk '/inet addr/{print substr($2,6)}'"
    proc = subprocess.Popen([shell_cmd], stdout=subprocess.PIPE, shell=True)
    (out, err) = proc.communicate()

    ip_list = out.split('\n')
    ip = ip_list[0]

    for _ip in ip_list:
        try:
            if _ip != "127.0.0.1" and _ip.split(".")[3] != "1":
                ip = _ip
        except:
            pass
    return ip, hostname

ip_addr, hostname = getIpAndHostname()
2 голосов
/ 29 апреля 2015

Это не очень Pythonic, но он надежно работает на Windows.

def getWinIP(version = 'IPv4'):
    import subprocess
    if version not in ['IPv4', 'IPv6']:
        print 'error - protocol version must be "IPv4" or "IPv6"'
        return None
    ipconfig = subprocess.check_output('ipconfig')
    my_ip = []
    for line in ipconfig.split('\n'):
        if 'Address' in line and version in line:
            my_ip.append(line.split(' : ')[1].strip())
    return my_ip

print getWinIP()

Да, это взлом, но порой мне не хочется переоценивать операционную систему, а просто продолжать и использовать то, что встроено и работает.

...