Вопрос

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

Это было полезно?

Решение

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

Это не всегда будет работать (возвращает 127.0.0.1 на машинах с именем хоста в / etc / hosts как 127.0.0.1 ) Палиативно будет то, что показывает гимел, используйте вместо этого socket.getfqdn () . Конечно, вашей машине нужно разрешаемое имя хоста.

Другие советы

Я только что нашел это, но это кажется немного хакерским, однако, говорят, попробовал это на * nix, а я на Windows, и это сработало.

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

Предполагается, что у вас есть доступ к Интернету, а локальный прокси отсутствует.

Этот метод возвращает «основной» IP-адрес локального ящика (того, который имеет маршрут по умолчанию)..

  • НЕ требует маршрутизируемого доступа к сети или какого-либо соединения вообще.
  • Работает, даже если все интерфейсы отключены от сети.
  • НЕ нуждается и даже не пытается получить где-нибудь еще.
  • Работает с NAT, общедоступными, частными, внешними и внутренними IP-адресами.
  • Чистый Python 2 (или 3) без внешних зависимостей.
  • Работает на Linux, Windows и OSX.

Питон 2 или 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

Это возвращает один IP-адрес, который является основным (тот, который имеет маршрут по умолчанию).Если вместо этого вам нужны все IP-адреса, подключенные ко всем интерфейсам (включая localhost и т. д.), см. этот ответ.

Если вы находитесь за брандмауэром NAT, например, за вашим Wi-Fi-прибором дома, тогда будет показан не ваш общедоступный IP-адрес NAT, а вместо этого ваш частный IP-адрес NAT в локальной сети, который имеет маршрут по умолчанию к вашему локальному маршрутизатору WIFI;для получения внешнего IP-адреса вашего Wi-Fi-маршрутизатора потребуется либо запустить его на ЭТОМ поле, либо подключиться к внешней службе, такой как whatismyip.com/whatismyipaddress.com, которая может отражать IP-адрес...но это полностью отличается от исходного вопроса.:)

Обновлен вызов Connect() по предложению Педро в комментариях.(Если вам нужно конкретное заявление о лицензии, это общедоступное/бесплатное для любого использования или MIT/CC2-BY-SA для каждой лицензии на код/контент Stack Overflow по вашему выбору.)

Как псевдоним под названием myip, это должно работать везде:

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])'"
  • Корректно работает с Python 2.x, Python 3.x, современными и старыми дистрибутивами Linux, OSX/macOS и Windows для поиска текущего адреса IPv4.
  • Не вернет правильный результат для компьютеров с несколькими IP-адресами, IPv6, без настроенного IP-адреса или без доступа в Интернет.

То же, что и выше, но только код 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])
  • Это вызовет исключение, если IP-адрес не настроен.

Версия, которая также будет работать в локальных сетях без подключения к Интернету:

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])

(Спасибо @ccpizza)


Фон:

С использованием socket.gethostbyname(socket.gethostname()) здесь не работало, потому что на одном из компьютеров, на которых я работал, был /etc/hosts с повторяющимися записями и ссылками на себя. socket.gethostbyname() возвращает только последнюю запись в /etc/hosts.

Это была моя первая попытка отсеять все адреса, начинающиеся с "127.":

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

Это работает с Python 2 и 3, в Linux и Windows, но не работает с несколькими сетевыми устройствами или IPv6.Однако он перестал работать в последних дистрибутивах Linux, поэтому вместо этого я попробовал этот альтернативный метод.Он пытается подключиться к DNS-серверу Google по адресу 8.8.8.8 в порту 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])

Затем я объединил два вышеуказанных метода в однострочник, который должен работать везде, и создал myip псевдоним и фрагмент Python в верхней части этого ответа.

С ростом популярности IPv6 и для серверов с несколькими сетевыми интерфейсами использование стороннего модуля Python для поиска IP-адреса, вероятно, является более надежным и надежным, чем любой из перечисленных здесь методов.

Вы можете использовать модуль netifaces . Просто введите:

pip install netifaces

в командной оболочке, и он будет установлен при установке Python по умолчанию.

Тогда вы можете использовать это так:

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))

На моем компьютере напечатано:

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

Автор этого модуля утверждает, что он должен работать в Windows, UNIX и Mac OS X.

Метод API сокетов

видеть https://stackoverflow.com/a/28950776/711085

Недостатки:

  • Не кроссплатформенный.
  • Требуется больше резервного кода, привязанного к существованию определенных адресов в Интернете.
  • Это также не будет работать, если вы находитесь за NAT.
  • Вероятно, создает UDP-соединение, независимое от доступности DNS (обычно интернет-провайдера) (см. другие ответы для таких идей, как использование 8.8.8.8:сервер Google (по совпадению также DNS)
  • Убедитесь, что вы сделали адрес назначения НЕДОСТУПНЫМ, например, числовой IP-адрес, который гарантированно не будет использоваться.НЕ используйте какой-либо домен, например fakesubdomain.google.com или somefakewebsite.com;вы по-прежнему будете рассылать спам этой стороне (сейчас или в будущем), а также рассылать спам в свои собственные сетевые ящики.

Рефлекторный метод

(Обратите внимание, что это не отвечает на вопрос ОП о локальном IP-адресе, например.192,168...;он дает вам ваш общедоступный IP-адрес, что может быть более желательно в зависимости от варианта использования.)

Вы можете запросить какой-нибудь сайт, например Whatismyip.com (но с API), например:

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)

или если вы используете 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)

Преимущества:

  • Одним из преимуществ этого метода является его кроссплатформенность.
  • Он работает из-за уродливых NAT (например.ваш домашний роутер).

Недостатки (и обходные пути):

  • Требуется, чтобы этот веб-сайт работал, формат не менялся (почти наверняка не изменится) и ваши DNS-серверы работали.Эту проблему можно смягчить, также запросив в случае сбоя другие сторонние отражатели IP-адресов.
  • Возможный вектор атаки, если вы не запрашиваете несколько отражателей (чтобы скомпрометированный отражатель не сообщил вам, что ваш адрес не является тем, чем он является), или если вы не используете HTTPS (чтобы предотвратить атаку «человек посередине», притворяющуюся быть сервером)

редактировать:Хотя поначалу я думал, что эти методы были действительно плохими (если вы не используете много запасных вариантов, код может быть неактуален через много лет), но они ставят вопрос: «Что такое Интернет?».Компьютер может иметь множество интерфейсов, указывающих на множество различных сетей.Более подробное описание темы можно найти в Google. gateways and routes.Компьютер может иметь доступ к внутренней сети через внутренний шлюз или доступ к всемирной паутине через шлюз, например, на маршрутизаторе (обычно так и есть).Локальный IP-адрес, о котором запрашивает ОП, четко определен только в отношении одного канального уровня, поэтому вам необходимо указать это («это сетевая карта или сетевой кабель, о котором мы говорим?») .На поставленный вопрос может быть несколько неуникальных ответов.Однако глобальный IP-адрес во всемирной паутине, вероятно, четко определен (при отсутствии массовой фрагментации сети):вероятно, обратный путь через шлюз, который может получить доступ к TLD.

Если у компьютера есть маршрут к Интернету, это всегда постарайтесь получить предпочтительный локальный IP-адрес, даже если /etc/hosts установлен неправильно.

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]

В 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'
>>> 

я использую следующий модуль:

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

Протестировано с Windows и Linux (и не требует дополнительных модулей для них) предназначен для использования в системах, которые находятся в одной локальной сети на основе IPv4.

Фиксированный список имен интерфейсов не работает в последних версиях linux, в которых было принято изменение systemd v197, касающееся предсказуемых имен интерфейсов, на что указывает Александр . В таких случаях вам нужно вручную заменить список именами интерфейсов в вашей системе или использовать другое решение, например netifaces .

Я использую это на своих машинах с Ubuntu:

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

Это не работает.

Если вы не хотите использовать внешние пакеты и не хотите полагаться на внешние интернет-серверы, это может помочь.Это пример кода, который я нашел на Поиск кода Google и изменен для возврата необходимой информации:

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

Использование:

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

Поскольку оно опирается на windll, это будет работать только в Windows.

Версия, которую я не верю, была опубликована. Я тестировал Python 2.7 на Ubuntu 12.04.

Нашел это решение по адресу:

На Debian (протестировано), и я подозреваю, что большинство Linux ..

import commands

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

В MS Windows (проверено)

import socket

socket.gethostbyname(socket.gethostname())

Вариация ответа Ниндзягецко. Это должно работать в любой локальной сети, которая разрешает широковещательную передачу UDP и не требует доступа к адресу в локальной сети или в Интернете.

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())

Боюсь, что не существует хороших независимых от платформы способов сделать это, кроме подключения к другому компьютеру и отправки вам вашего IP-адреса. Например: findmyipaddress . Обратите внимание, что это не будет работать, если вам нужен IP-адрес, который находится за NAT, если только компьютер, к которому вы подключаетесь, не находится за NAT.

Вот одно решение, которое работает в Linux: получить IP-адрес, связанный с сетевым интерфейсом .

Один простой способ создать " чистый " вывод через утилиты командной строки:

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

Он покажет все адреса IPv4 в системе.

К вашему сведению, я могу убедиться, что метод:

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

Работает в OS X (10.6,10.5), Windows XP и на хорошо управляемом сервере отдела RHEL. Он не работал на очень минимальной виртуальной машине CentOS, на которой я просто взломал ядро. Поэтому для этого экземпляра вы можете просто проверить адрес 127.0.0.1 и в этом случае сделать следующее:

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

А затем проанализируйте IP-адрес из вывода. Следует отметить, что ifconfig не входит в PATH обычного пользователя по умолчанию, и поэтому я даю полный путь в команде. Надеюсь, это поможет.

Это вариант ответа UnkwnTech - он предоставляет функцию get_local_addr () , которая возвращает основной IP-адрес локальной сети хоста. Я публикую его, потому что это добавляет ряд вещей: поддержку ipv6, обработку ошибок, игнорирование адресов localhost / linklocal и использование адреса TESTNET (rfc5737) для подключения.

# 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

Это будет работать на большинстве 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()
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]

Этот ответ - моя личная попытка решить проблему получения 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())

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.

Небольшое уточнение версии команд, которая использует команду 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)]

Что ж, вы можете использовать команду «ip маршрут» в 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'])

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

$ pip install pif

from pif import get_public_ip
get_public_ip()

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

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

  • Интерфейс localhost/loopback не всегда может быть включен (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)

Наслаждаться!

Чтобы получить IP-адрес, вы можете использовать команду shell непосредственно в 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()
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.

Если вы ищете адрес 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-адрес.

Мне пришлось решить проблему "Выяснить, является ли IP-адрес локальным или нет", и моей первой мыслью было создание списка IP-адресов, которые были локальными, а затем сопоставлялись с ним. Это то, что привело меня к этому вопросу. Однако позже я понял, что есть более простой способ сделать это: попробуйте привязать этот IP и посмотреть, работает ли он.

_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

Я знаю, что это не дает прямого ответа на вопрос, но это должно быть полезно для всех, кто пытается решить связанный вопрос, и кто следовал тому же ходу мыслей. Это имеет то преимущество, что является кроссплатформенным решением (я думаю).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top