Получение внешнего IP-адреса компьютера с помощью Python
В поисках лучшего способа получить машины с текущим внешним IP-адресом... Ниже работает, но я бы предпочел не полагаться на внешний сайт для сбора информации... Я ограничен использованием стандартных библиотек Python 2.5.1 в комплекте с Mac OS X 10.5.x
import os
import urllib2
def check_in():
fqn = os.uname()[1]
ext_ip = urllib2.urlopen('http://whatismyip.org').read()
print ("Asset: %s " % fqn, "Checking in from IP#: %s " % ext_ip)
35 ответов
Если вы находитесь за маршрутизатором, который получает внешний IP, я боюсь, что у вас нет другого выбора, кроме как использовать внешний сервис, как вы. Если у самого маршрутизатора есть некоторый интерфейс запросов, вы можете использовать его, но решение будет очень специфичным для среды и ненадежным.
Мне понравился http://ipify.org/. Они даже предоставляют код Python для использования их API.
# This example requires the requests library be installed. You can learn more
# about the Requests library here: http://docs.python-requests.org/en/latest/
from requests import get
ip = get('https://api.ipify.org').text
print 'My public IP address is:', ip
Python3, не используя ничего, кроме стандартной библиотеки
Как упоминалось ранее, нельзя обойтись использованием какой-либо внешней службы для обнаружения внешнего IP-адреса вашего маршрутизатора.
Вот как это делается с python3
, не используя ничего, кроме стандартной библиотеки:
import urllib.request
external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
print(external_ip)
Я написал для этого модуль: ipgetter. Предназначен для получения вашего внешнего IP-адреса из Интернета. Он используется в основном за NAT. Он выбирает ваш IP случайным образом из списка серверов, чтобы минимизировать накладные расходы на запрос на одном сервере. Фактически с 44 сервером и тестовой функцией, чтобы проверить, возвращают ли серверы тот же IP.
https://github.com/phoemur/ipgetter
выглядит так:
>>> import ipgetter
>>> IP = ipgetter.myip()
>>> print(IP)
'xxx.xxx.xxx.xxx'
>>> ipgetter.IPgetter().test()
Number of servers: 44
IP's :
'xxx.xxx.xxx.xxx' = 44 ocurrencies
I prefer this Amazon AWS endpoint:
import requests
ip = requests.get('https://checkip.amazonaws.com').text.strip()
Вы должны использовать протокол UPnP, чтобы запросить у вашей роутера эту информацию. Самое главное, что это не зависит от внешней службы, которая, как представляется, предлагают все другие ответы на этот вопрос.
Есть библиотека Python с именем miniupnp, которая может сделать это, см., Например, miniupnpc / testupnpigd.py.
pip install miniupnpc
Основываясь на их примере, вы сможете сделать что-то вроде этого:
import miniupnpc
u = miniupnpc.UPnP()
u.discoverdelay = 200
u.discover()
u.selectigd()
print('external ip address: {}'.format(u.externalipaddress()))
На мой взгляд, самое простое решение
f = requests.request('GET', 'http://myip.dnsomatic.com')
ip = f.text
Это все.
Использовать модуль запросов:
import requests
myip = requests.get('https://www.wikipedia.org').headers['X-Client-IP']
print("\n[+] Public IP: "+myip)
Так же просто, как запустить это в Python3:
import os
externalIP = os.popen('curl -s ifconfig.me').readline()
print(externalIP)
Если вы не хотите использовать внешние сервисы (IP-сайты и т. Д.), Вы можете использовать протокол UPnP.
Для этого мы используем простую клиентскую библиотеку UPnP ( https://github.com/flyte/upnpclient)
Установить:
pip install upnpclient
Простой код:
import upnpclient
devices = upnpclient.discover()
if(len(devices) > 0):
externalIP = devices[0].WANIPConn1.GetExternalIPAddress()
print(externalIP)
else:
print('No Connected network interface detected')
Полный код (чтобы получить больше информации, как указано в readme github)
In [1]: import upnpclient
In [2]: devices = upnpclient.discover()
In [3]: devices
Out[3]:
[<Device 'OpenWRT router'>,
<Device 'Harmony Hub'>,
<Device 'walternate: root'>]
In [4]: d = devices[0]
In [5]: d.WANIPConn1.GetStatusInfo()
Out[5]:
{'NewConnectionStatus': 'Connected',
'NewLastConnectionError': 'ERROR_NONE',
'NewUptime': 14851479}
In [6]: d.WANIPConn1.GetNATRSIPStatus()
Out[6]: {'NewNATEnabled': True, 'NewRSIPAvailable': False}
In [7]: d.WANIPConn1.GetExternalIPAddress()
Out[7]: {'NewExternalIPAddress': '123.123.123.123'}
Пытаться:
import requests
ip = requests.get('http://ipinfo.io/json').json()['ip']
Надеюсь, это будет полезно
Если вы считаете, что внешний источник слишком ненадежен, вы можете объединить несколько разных сервисов. Для большинства страниц поиска по ip требуется, чтобы вы просмотрели html, но некоторые из них создали скудные страницы для таких сценариев, как ваш, а также чтобы уменьшить количество обращений на свои сайты:
- http://automation.whatismyip.com/n09230945.asp (Обновление: whatismyip отключил этот сервис)
- http://whatismyip.org/
Я использую IPGrab, потому что его легко запомнить:
# This example requires the requests library be installed. You can learn more
# about the Requests library here: http://docs.python-requests.org/en/latest/
from requests import get
ip = get('http://ipgrab.io').text
print('My public IP address is: {}'.format(ip))
Есть несколько других способов, которые не полагаются на проверку Python внешнего веб-сайта, однако ОС может. Ваша главная проблема здесь заключается в том, что даже если вы не использовали Python, если вы использовали командную строку, не существует "встроенных" команд, которые могут просто сообщить вам внешний (WAN) IP. Такие команды, как "ip addr show" и "ifconfig -a", показывают IP-адрес сервера в сети. Только роутер фактически держит внешний IP. Однако есть способы найти внешний IP-адрес (WAN IP) из командной строки.
Эти примеры:
http://ipecho.net/plain ; echo
curl ipinfo.io/ip
dig +short myip.opendns.com @resolver1.opendns.com
dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
Следовательно, код Python будет:
import os
ip = os.popen('wget -qO- http://ipecho.net/plain ; echo').readlines(-1)[0].strip()
print ip
ИЛИ ЖЕ
import os
iN, out, err = os.popen3('curl ipinfo.io/ip')
iN.close() ; err.close()
ip = out.read().strip()
print ip
ИЛИ ЖЕ
import os
ip = os.popen('dig +short myip.opendns.com @resolver1.opendns.com').readlines(-1)[0].strip()
print ip
Или подключите любой другой из приведенных выше примеров к такой команде, как os.popen, os.popen2, os.popen3 или os.system.
К сожалению, невозможно получить внешний IP-адрес без обращения к компьютеру в Интернете. В лучшем случае вы можете получить локальный сетевой IP-адрес вашей сетевой карты (скорее всего, это адрес 192.16.. ) .
Вы можете использовать
pip install whatismyip
Пример:
>>> import whatismyip
>>> whatismyip.amionline()
True
>>> whatismyip.whatismyip() # Prefers IPv4 addresses, but can return either IPv4 or IPv6.
'69.89.31.226'
>>> whatismyip.whatismyipv4()
'69.89.31.226'
>>> whatismyip.whatismyipv6()
'2345:0425:2CA1:0000:0000:0567:5673:23b5'
import requests
import re
def getMyExtIp():
try:
res = requests.get("http://whatismyip.org")
myIp = re.compile('(\d{1,3}\.){3}\d{1,3}').search(res.text).group()
if myIp != "":
return myIp
except:
pass
return "n/a"
Единственное решение для Linux.
В системах Linux вы можете использовать Python для выполнения команды в оболочке. Я думаю, это может кому-то помочь.
Что-то вроде этого (при условии, что в ОС работает "копать / сверлить")
import os
command = "dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F\'\"\' '{print $2}' "
ip = os.system(command)
Для пользователей Arch: замените "копать" на "сверлить".
Самое простое (не python) рабочее решение, которое я могу придумать,
wget -q -O- icanhazip.com
Я хотел бы добавить очень короткое решение Python3, которое использует JSON API http://hostip.info/.
from urllib.request import urlopen
import json
url = 'http://api.hostip.info/get_json.php'
info = json.loads(urlopen(url).read().decode('utf-8'))
print(info['ip'])
Конечно, вы можете добавить проверку ошибок, состояние тайм-аута и некоторое удобство:
#!/usr/bin/env python3
from urllib.request import urlopen
from urllib.error import URLError
import json
try:
url = 'http://api.hostip.info/get_json.php'
info = json.loads(urlopen(url, timeout = 15).read().decode('utf-8'))
print(info['ip'])
except URLError as e:
print(e.reason, end=' ') # e.g. 'timed out'
print('(are you connected to the internet?)')
except KeyboardInterrupt:
pass
Я попробовал большинство других ответов на этот вопрос здесь и пришел к выводу, что большинство использованных сервисов перестали существовать, кроме одного.
Вот скрипт, который должен сделать трюк и загрузить только минимальное количество информации:
#!/usr/bin/env python
import urllib
import re
def get_external_ip():
site = urllib.urlopen("http://checkip.dyndns.org/").read()
grab = re.findall('([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', site)
address = grab[0]
return address
if __name__ == '__main__':
print( get_external_ip() )
Работа с Python 2.7.6 и 2.7.13
import urllib2
req = urllib2.Request('http://icanhazip.com', data=None)
response = urllib2.urlopen(req, timeout=5)
print(response.read())
In [1]: import stun
stun.get_ip_info()
('Restric NAT', 'xx.xx.xx.xx', 55320)
Мне понравился ответ Сергея Островского , но я думаю, что сейчас есть еще более аккуратный способ сделать это.
- Установите библиотеку ipify .
pip install ipify
- Импортируйте и используйте библиотеку в своей программе Python.
import ipify
ip = ipify.get_ip()
Если машина является брандмауэром, то ваше решение очень разумно: альтернатива заключается в том, чтобы запросить брандмауэр, который в конечном итоге сильно зависит от типа брандмауэра (если это вообще возможно).
Если вы пишете только для себя, а не для обобщенного приложения, вы можете найти адрес на странице настройки вашего маршрутизатора, а затем убрать его из html этой страницы. Это работало хорошо для меня с моим маршрутизатором SMC. Один прочитанный и один простой поиск RE, и я нашел это.
Мой особый интерес к этому состоял в том, чтобы сообщить мне мой домашний IP-адрес, когда я был вдали от дома, чтобы я мог вернуться через VNC. Еще несколько строк Python хранят адрес в Dropbox для внешнего доступа и даже отправляют мне электронные письма, если он видит изменение. Я запланировал, что это произойдет при загрузке и один раз в час после этого.
Вышеуказанные ответы либо устарели, либо сложны. В настоящее время это работает на последней версии Python 3.11=
import urllib.request
import json
def get_external_ip():
try:
response = urllib.request.urlopen("https://httpbin.org/ip")
data = json.load(response)
address = data['origin']
return address
except Exception as e:
return str(e)
if __name__ == '__main__':
print(get_external_ip())
import ospublic_ip = os.system("inxi -i |grep 'WAN IP'")print(public_ip)
ipWebCode = urllib.request.urlopen("http://ip.nefsc.noaa.gov").read().decode("utf8")
ipWebCode=ipWebCode.split("color=red> ")
ipWebCode = ipWebCode[1]
ipWebCode = ipWebCode.split("</font>")
externalIp = ipWebCode[0]
это короткий фрагмент, который я написал для другой программы. Хитрость заключалась в том, чтобы найти достаточно простой веб-сайт, чтобы разбирать HTML не было проблемой.
Чтобы получить внешний IP-адрес, используйте этот код:
from requests import get
def get_external_ip()->str:
return get('https://api.ipify.org/').text
Используйте этот скрипт:
import urllib, json
data = json.loads(urllib.urlopen("http://ip.jsontest.com/").read())
print data["ip"]
Без json:
import urllib, re
data = re.search('"([0-9.]*)"', urllib.urlopen("http://ip.jsontest.com/").read()).group(1)
print data
Вот еще один альтернативный скрипт.
def track_ip():
"""
Returns Dict with the following keys:
- ip
- latlong
- country
- city
- user-agent
"""
conn = httplib.HTTPConnection("www.trackip.net")
conn.request("GET", "/ip?json")
resp = conn.getresponse()
print resp.status, resp.reason
if resp.status == 200:
ip = json.loads(resp.read())
else:
print 'Connection Error: %s' % resp.reason
conn.close()
return ip
РЕДАКТИРОВАТЬ: не забудьте импортировать httplib и json