obtener hacer con como python networking ip-address

obtener - como hacer ping con python



Encontrar direcciones IP locales usando el stdlib de Python (30)

Acabo de encontrar esto, pero parece un poco intrincado, sin embargo, dicen que lo probé en * nix y lo hice en Windows y funcionó.

import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) print(s.getsockname()[0]) s.close()

Esto supone que tiene acceso a Internet y que no hay un proxy local.

¿Cómo puedo encontrar direcciones IP locales (es decir, 192.168.xx o 10.0.xx) en la plataforma Python de forma independiente y utilizando solo la biblioteca estándar?


En Debian (probado) y sospecho que la mayoría de los Linux ...

import commands RetMyIP = commands.getoutput("hostname -I")

En MS Windows (probado)

import socket socket.gethostbyname(socket.gethostname())


En Linux:

>>> import socket, struct, fcntl >>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) >>> sockfd = sock.fileno() >>> SIOCGIFADDR = 0x8915 >>> >>> def get_ip(iface = ''eth0''): ... ifreq = struct.pack(''16sH14s'', iface, socket.AF_INET, ''/x00''*14) ... try: ... res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq) ... except: ... return None ... ip = struct.unpack(''16sH2x4s8x'', res)[2] ... return socket.inet_ntoa(ip) ... >>> get_ip(''eth0'') ''10.80.40.234'' >>>


Esta es una variante de la respuesta de UnkwnTech: proporciona una función get_local_addr() , que devuelve la dirección IP de LAN principal del host. Lo estoy publicando porque esto agrega una serie de cosas: compatibilidad con ipv6, manejo de errores, ignorando localhost / linklocal addrs, y usa un addr de TESTNET (rfc5737) para conectarse.

# imports import errno import socket # localhost prefixes _local_networks = ("127.", "0:0:0:0:0:0:0:1") # ignore these prefixes -- localhost, unspecified, and link-local _ignored_networks = _local_networks + ("0.", "0:0:0:0:0:0:0:0", "169.254.", "fe80:") def detect_family(addr): if "." in addr: assert ":" not in addr return socket.AF_INET elif ":" in addr: return socket.AF_INET6 else: raise ValueError("invalid ipv4/6 address: %r" % addr) def expand_addr(addr): """convert address into canonical expanded form -- no leading zeroes in groups, and for ipv6: lowercase hex, no collapsed groups. """ family = detect_family(addr) addr = socket.inet_ntop(family, socket.inet_pton(family, addr)) if "::" in addr: count = 8-addr.count(":") addr = addr.replace("::", (":0" * count) + ":") if addr.startswith(":"): addr = "0" + addr return addr def _get_local_addr(family, remote): try: s = socket.socket(family, socket.SOCK_DGRAM) try: s.connect((remote, 9)) return s.getsockname()[0] finally: s.close() except socket.error: return None def get_local_addr(remote=None, ipv6=True): """get LAN address of host :param remote: return LAN address that host would use to access that specific remote address. by default, returns address it would use to access the public internet. :param ipv6: by default, attempts to find an ipv6 address first. if set to False, only checks ipv4. :returns: primary LAN address for host, or ``None`` if couldn''t be determined. """ if remote: family = detect_family(remote) local = _get_local_addr(family, remote) if not local: return None if family == socket.AF_INET6: # expand zero groups so the startswith() test works. local = expand_addr(local) if local.startswith(_local_networks): # border case where remote addr belongs to host return local else: # NOTE: the two addresses used here are TESTNET addresses, # which should never exist in the real world. if ipv6: local = _get_local_addr(socket.AF_INET6, "2001:db8::1234") # expand zero groups so the startswith() test works. if local: local = expand_addr(local) else: local = None if not local: local = _get_local_addr(socket.AF_INET, "192.0.2.123") if not local: return None if local.startswith(_ignored_networks): return None return local


Esta respuesta es mi intento personal de resolver el problema de obtener la IP de LAN, ya que socket.gethostbyname(socket.gethostname()) también devolvió 127.0.0.1.Este método no requiere Internet solo una conexión LAN. El código es para Python 3.x pero se puede convertir fácilmente para 2.x. Utilizando 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())


Esto funcionará en la mayoría de las cajas de linux:

import socket, subprocess, re def get_ipv4_address(): """ Returns IP address(es) of current machine. :return: """ p = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE) ifc_resp = p.communicate() patt = re.compile(r''inet/s*/w*/S*:/s*(/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3})'') resp = patt.findall(ifc_resp[0]) print resp get_ipv4_address()


Estoy usando el siguiente módulo:

#!/usr/bin/python # module for getting the lan ip address of the computer import os import socket if os.name != "nt": import fcntl import struct def get_interface_ip(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack(''256s'', bytes(ifname[:15], ''utf-8'')) # Python 2.7: remove the second argument for the bytes call )[20:24]) def get_lan_ip(): ip = socket.gethostbyname(socket.gethostname()) if ip.startswith("127.") and os.name != "nt": interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"] for ifname in interfaces: try: ip = get_interface_ip(ifname) break; except IOError: pass return ip

Probado con Windows y Linux (y no requiere módulos adicionales para aquellos) destinados para uso en sistemas que están en una única LAN basada en IPv4.

La lista fija de nombres de interfaz no funciona para las versiones recientes de Linux, que han adoptado el cambio systemd v197 con respecto a los nombres de interfaz predecibles como lo señaló Alexander . En tales casos, debe reemplazar manualmente la lista con los nombres de interfaz en su sistema, o usar otra solución como netifaces .


FYI puedo verificar que el método:

import socket addr = socket.gethostbyname(socket.gethostname())

Funciona en OS X (10.6,10.5), Windows XP y en un servidor de departamento RHEL bien administrado. No funcionó en una máquina virtual CentOS muy mínima en la que acabo de piratear el kernel. Por lo tanto, para esa instancia, solo puede verificar una dirección 127.0.0.1 y, en ese caso, hacer lo siguiente:

if addr == "127.0.0.1": import commands output = commands.getoutput("/sbin/ifconfig") addr = parseaddress(output)

Y luego analizar la dirección IP de la salida. Se debe tener en cuenta que ifconfig no está en la RUTA de un usuario normal de forma predeterminada y es por eso que proporciono la ruta completa en el comando. Espero que esto ayude.


Me temo que no existen otras formas independientes de buena plataforma para hacer esto que no sea conectarse a otra computadora y pedirle que le envíe su dirección IP. Por ejemplo: findmyipaddress . Tenga en cuenta que esto no funcionará si necesita una dirección IP que esté detrás de NAT a menos que la computadora a la que se conecte también esté detrás de NAT.

Aquí hay una solución que funciona en Linux: obtenga la dirección IP asociada con una interfaz de red .


Puede utilizar el módulo de netifaces . Sólo tipo:

pip install netifaces

en su shell de comandos y se instalará en la instalación predeterminada de Python.

Entonces puedes usarlo así:

from netifaces import interfaces, ifaddresses, AF_INET for ifaceName in interfaces(): addresses = [i[''addr''] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{''addr'':''No IP addr''}] )] print ''%s: %s'' % (ifaceName, '', ''.join(addresses))

En mi computadora se imprimió:

{45639BDC-1050-46E0-9BE9-075C30DE1FBC}: 192.168.0.100 {D43A468B-F3AE-4BF9-9391-4863A4500583}: 10.5.9.207

El autor de este módulo afirma que debería funcionar en Windows, UNIX y Mac OS X.


Si la computadora tiene una ruta a Internet, esto siempre funcionará para obtener la dirección IP local preferida, incluso si / etc / hosts no está configurado correctamente.

import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect((''8.8.8.8'', 1)) # connect() for UDP doesn''t send packets local_ip_address = s.getsockname()[0]


Si no quiere usar paquetes externos y no quiere depender de servidores de Internet externos, esto podría ayudar. Es un ejemplo de código que encontré en Google Code Search y modifiqué para devolver la información requerida:

def getIPAddresses(): from ctypes import Structure, windll, sizeof from ctypes import POINTER, byref from ctypes import c_ulong, c_uint, c_ubyte, c_char MAX_ADAPTER_DESCRIPTION_LENGTH = 128 MAX_ADAPTER_NAME_LENGTH = 256 MAX_ADAPTER_ADDRESS_LENGTH = 8 class IP_ADDR_STRING(Structure): pass LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING) IP_ADDR_STRING._fields_ = [ ("next", LP_IP_ADDR_STRING), ("ipAddress", c_char * 16), ("ipMask", c_char * 16), ("context", c_ulong)] class IP_ADAPTER_INFO (Structure): pass LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO) IP_ADAPTER_INFO._fields_ = [ ("next", LP_IP_ADAPTER_INFO), ("comboIndex", c_ulong), ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)), ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)), ("addressLength", c_uint), ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH), ("index", c_ulong), ("type", c_uint), ("dhcpEnabled", c_uint), ("currentIpAddress", LP_IP_ADDR_STRING), ("ipAddressList", IP_ADDR_STRING), ("gatewayList", IP_ADDR_STRING), ("dhcpServer", IP_ADDR_STRING), ("haveWins", c_uint), ("primaryWinsServer", IP_ADDR_STRING), ("secondaryWinsServer", IP_ADDR_STRING), ("leaseObtained", c_ulong), ("leaseExpires", c_ulong)] GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo GetAdaptersInfo.restype = c_ulong GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)] adapterList = (IP_ADAPTER_INFO * 10)() buflen = c_ulong(sizeof(adapterList)) rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen)) if rc == 0: for a in adapterList: adNode = a.ipAddressList while True: ipAddr = adNode.ipAddress if ipAddr: yield ipAddr adNode = adNode.next if not adNode: break

Uso:

>>> for addr in getIPAddresses(): >>> print addr 192.168.0.100 10.5.9.207

Como se basa en windll , esto funcionará solo en Windows.


Una forma sencilla de producir resultados "limpios" a través de las utils de línea de comandos:

import commands ips = commands.getoutput("/sbin/ifconfig | grep -i /"inet/" | grep -iv /"inet6/" | " + "awk {''print $2''} | sed -ne ''s/addr/:/ /p''") print ips

Mostrará todas las direcciones IPv4 en el sistema.


Una versión que no creo que haya sido publicada aún. He probado con python 2.7 en Ubuntu 12.04.

Encontré esta solución en: http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/

import socket import fcntl import struct def get_ip_address(ifname): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack(''256s'', ifname[:15]) )[20:24])

Resultado de ejemplo:

>>> get_ip_address(''eth0'') ''38.113.228.130''


Variación en la respuesta de ninjagecko. Esto debería funcionar en cualquier LAN que permita la transmisión UDP y no requiera acceso a una dirección en la LAN o Internet.

import socket def getNetworkIp(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.connect((''<broadcast>'', 0)) return s.getsockname()[0] print (getNetworkIp())


Yo uso esto en mis máquinas de ubuntu:

import commands commands.getoutput("/sbin/ifconfig").split("/n")[1].split()[1][5:]

Esto no funciona.


127.0.1.1 Es tu dirección IP real. En términos más generales, una computadora puede tener cualquier número de direcciones IP. Puede filtrarlos para redes privadas: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 y 192.168.0.0/16.

Sin embargo, no existe una forma multiplataforma para obtener todas las direcciones IP. En Linux, puedes usar el SIOCGIFCONFioctl.


Como un alias llamado myip , debería funcionar en todas partes:

alias myip="python -c ''import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(/"127./")][:1], [[(s.connect((/"8.8.8.8/", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])''"

  • Funciona correctamente con Python 2.x, Python 3.x, distribuciones de Linux modernas y antiguas, OSX / macOS y Windows para encontrar la dirección IPv4 actual.
  • No devolverá el resultado correcto para máquinas con múltiples direcciones IP, IPv6, sin una dirección IP configurada o sin acceso a Internet.

Igual que el anterior, pero solo el código de Python:

import socket print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect((''8.8.8.8'', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])

  • Esto producirá una excepción si no se configura una dirección IP.

Versión que también funcionará en redes LAN sin conexión a internet:

import socket print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])

(gracias @ccpizza )

Antecedentes

El uso de socket.gethostbyname(socket.gethostname()) no funcionó aquí, porque una de las computadoras en las que estaba tenía un /etc/hosts con entradas duplicadas y referencias a sí mismo. socket.gethostbyname() solo devuelve la última entrada en /etc/hosts .

Este fue mi primer intento, que elimina todas las direcciones que comienzan con "127." :

import socket print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])

Esto funciona con Python 2 y 3, en Linux y Windows, pero no trata con varios dispositivos de red o IPv6. Sin embargo, dejó de funcionar en distribuciones de Linux recientes, así que probé esta técnica alternativa en su lugar. Intenta conectarse al servidor DNS de Google en 8.8.8.8 en el puerto 53 :

import socket print([(s.connect((''8.8.8.8'', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])

Luego combiné las dos técnicas anteriores en una sola línea que debería funcionar en todas partes, y creé el alias myip y el fragmento de Python en la parte superior de esta respuesta.

Con la creciente popularidad de IPv6, y para servidores con múltiples interfaces de red, el uso de un módulo Python de terceros para encontrar la dirección IP es probablemente más robusto y confiable que cualquiera de los métodos enumerados aquí.


Este método devuelve la IP "primaria" en el cuadro local (el que tiene una ruta predeterminada) .

  • NO necesita acceso a la red enrutable o cualquier conexión.
  • Funciona incluso si todas las interfaces están desconectadas de la red.
  • NO necesita ni intenta llegar a ningún otro lugar .
  • Funciona con NAT, IP públicas, privadas, externas e internas.
  • Pure Python 2 (o 3) sin dependencias externas.
  • Funciona en Linux, Windows y OSX.

Python 2 o 3:

import socket def get_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: # doesn''t even have to be reachable s.connect((''10.255.255.255'', 1)) IP = s.getsockname()[0] except: IP = ''127.0.0.1'' finally: s.close() return IP

Esto devuelve una única IP, que es la principal (la que tiene una ruta predeterminada). Si necesita, en cambio, todas las direcciones IP conectadas a todas las interfaces (incluido localhost, etc.), vea esta respuesta .

Si está detrás de un firewall NAT como su caja wifi en casa, esto no mostrará su NAT IP pública, sino su IP NAT privada en la red local que tiene una ruta predeterminada a su enrutador WIFI local; obtener la IP externa de su enrutador wifi requeriría ejecutar esto en ESA caja, o conectarse a un servicio externo como whatismyip.com/whatismyipaddress.com que podría reflejar la IP ... pero eso es completamente diferente de la pregunta original. :)

Llamada connect () actualizada según la sugerencia de Pedro en los comentarios. (Si necesita una declaración de licencia específica, se trata de un dominio público / gratuito para cualquier uso, o MIT / CC2-BY-SA según la licencia de código / contenido de a su elección).


Método API de socket

vea https://.com/a/28950776/711085

Desventajas:

  • No multiplataforma.
  • Requiere más código de respaldo, vinculado a la existencia de direcciones particulares en Internet
  • Esto tampoco funcionará si estás detrás de un NAT
  • Probablemente crea una conexión UDP, no independiente de la disponibilidad de DNS (normalmente ISP) (ver otras respuestas para ideas como usar 8.8.8.8: servidor de Google (casualmente también DNS))
  • Asegúrate de que la dirección de destino sea irrecuperable, como una dirección IP numérica que se garantiza que no se use. NO use algún dominio como fakesubdomain.google.com o somefakewebsite.com; seguirá siendo spam esa parte (ahora o en el futuro), y también spamming sus propias cajas de red en el proceso.

Metodo reflector

(Tenga en cuenta que esto no responde a la pregunta del OP sobre la dirección IP local, por ejemplo, 192.168 ...; le proporciona su dirección IP pública, que podría ser más conveniente dependiendo del caso de uso).

Puede consultar algún sitio como whatismyip.com (pero con una API), como:

from urllib.request import urlopen import re def getPublicIp(): data = str(urlopen(''http://checkip.dyndns.com/'').read()) # data = ''<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>/r/n'' return re.compile(r''Address: (/d+/./d+/./d+/./d+)'').search(data).group(1)

o si usas python2:

from urllib import urlopen import re def getPublicIp(): data = str(urlopen(''http://checkip.dyndns.com/'').read()) # data = ''<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>/r/n'' return re.compile(r''Address: (/d+/./d+/./d+/./d+)'').search(data).group(1)

Ventajas:

  • Una ventaja de este método es su multiplataforma
  • Funciona desde detrás de NAT feos (por ejemplo, el enrutador de su casa).

Desventajas (y soluciones):

  • Requiere que este sitio web esté activo, que el formato no cambie (seguramente no lo hará) y que los servidores DNS funcionen. Uno puede mitigar este problema al consultar otros reflectores de direcciones IP de terceros en caso de falla.
  • Posible vector de ataque si no consulta múltiples reflectores (para evitar que un reflector comprometido le diga que su dirección es algo que no lo es), o si no usa HTTPS (para evitar un ataque de hombre en el medio que simula) ser el servidor)

Edit : Aunque inicialmente pensé que estos métodos eran realmente malos (a menos que use muchos recursos alternativos, el código puede ser irrelevante dentro de muchos años), plantea la pregunta "¿qué es Internet?". Una computadora puede tener muchas interfaces que apuntan a muchas redes diferentes. Para una descripción más detallada del tema, busque las gateways and routes de gateways and routes Google. Una computadora puede ser capaz de acceder a una red interna a través de una puerta de enlace interna, o acceder a la red mundial a través de una puerta de enlace, por ejemplo, en un enrutador (generalmente el caso). La dirección IP local que solicita el OP solo está bien definida con respecto a una sola capa de enlace, por lo que debe especificar que "es la tarjeta de red o el cable Ethernet, ¿de qué estamos hablando?" . Puede haber múltiples respuestas no únicas a esta pregunta como se plantea. Sin embargo, la dirección IP global en la red mundial probablemente esté bien definida (en ausencia de una fragmentación masiva de la red): probablemente la ruta de retorno a través de la puerta de enlace que puede acceder a los TLD.


Bueno, puede usar el comando "ip route" en GNU / Linux para conocer su dirección IP actual.

Esto muestra la IP dada a la interfaz por el servidor DHCP que se ejecuta en el enrutador / módem. Por lo general, "192.168.1.1/24" es la IP de la red local donde "24" significa el rango de posibles direcciones IP que proporciona el servidor DHCP dentro del rango de la máscara.

Aquí hay un ejemplo: tenga en cuenta que PyNotify es solo una adición para aclarar mi punto y no es necesario en absoluto

#! /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()

La ventaja de esto es que no necesita especificar la interfaz de red. Eso es bastante útil cuando se ejecuta un servidor de socket

Puedes instalar PyNotify usando easy_install o incluso Pip:

easy_install py-notify

o

pip install py-notify

o dentro de script / intérprete de python

from pip import main main([''install'', ''py-notify''])


Nota: Esto no está utilizando la biblioteca estándar, pero es bastante simple.

$ pip install pif

from pif import get_public_ip get_public_ip()


Un ligero refinamiento de la versión de los comandos que utiliza el comando IP y devuelve las direcciones IPv4 e 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)]


Para obtener la dirección IP, puede usar un comando de shell directamente en 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()


Tuve que resolver el problema "Averiguar si una dirección IP es local o no", y lo primero que pensé fue crear una lista de IP que fueran locales y luego compararlas. Esto es lo que me llevó a esta pregunta. Sin embargo, más tarde me di cuenta de que hay una forma más directa de hacerlo: intente enlazar esa IP y ver si funciona.

_local_ip_cache = [] _nonlocal_ip_cache = [] def ip_islocal(ip): if ip in _local_ip_cache: return True if ip in _nonlocal_ip_cache: return False s = socket.socket() try: try: s.bind((ip, 0)) except socket.error, e: if e.args[0] == errno.EADDRNOTAVAIL: _nonlocal_ip_cache.append(ip) return False else: raise finally: s.close() _local_ip_cache.append(ip) return True

Sé que esto no responde directamente a la pregunta, pero debería ser útil para cualquiera que intente resolver la pregunta relacionada y quién sigue el mismo pensamiento. Esto tiene la ventaja de ser una solución multiplataforma (creo).


netifaces está disponible a través de pip y easy_install. (Lo sé, no está en la base, pero podría valer la pena la instalación).

netifaces tiene algunas rarezas en las plataformas:

  • La interfaz localhost / loop-back puede no estar siempre incluida (Cygwin).
  • Las direcciones se enumeran por protocolo (por ejemplo, IPv4, IPv6) y los protocolos se enumeran por interfaz. En algunos sistemas (Linux), cada par de interfaz de protocolo tiene su propia interfaz asociada (usando la notación de interface_name: n) mientras que en otros sistemas (Windows), una única interfaz tendrá una lista de direcciones para cada protocolo. En ambos casos, hay una lista de protocolos, pero puede contener un solo elemento.

Aquí hay un código de netifaces para jugar:

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.

El código anterior no asigna una dirección a su nombre de interfaz (útil para generar reglas de ebtables / iptables sobre la marcha). Así que aquí hay una versión que mantiene la información anterior con el nombre de la interfaz en una tupla:

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]

Y, no, no estoy enamorado de las listas de comprensión. Así es como funciona mi cerebro en estos días.

El siguiente fragmento de código lo imprimirá todo:

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)

¡Disfrutar!


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

Esto le devolverá la dirección IP en el sistema Ubuntu, así como MacOS. La salida será la dirección IP del sistema como mi IP: 192.168.1.10.


import socket [i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]


import socket socket.gethostbyname(socket.getfqdn())


import socket socket.gethostbyname(socket.gethostname())

Esto no funcionará siempre (devuelve 127.0.0.1 en máquinas que tienen el nombre de host en /etc/hosts como 127.0.0.1 ), un paliativo sería lo que muestra gimel; en su lugar, use socket.getfqdn() . Por supuesto, su máquina necesita un nombre de host resoluble.