web-dev-qa-db-fra.com

Obtenir l'adresse IP externe d'une machine avec Python

Vous recherchez un meilleur moyen d'obtenir le numéro IP externe actuel d'une machine ... Les informations ci-dessous fonctionnent, mais ne souhaitez pas vous fier à un site extérieur pour collecter les informations ... Je suis limité à l'utilisation des bibliothèques standard Python 2.5.1 fournies avec 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)
43
cit

Si vous êtes derrière un routeur qui obtient l'IP externe, je crains que vous n'ayez pas d'autre choix que d'utiliser un service externe comme vous le faites. Si le routeur lui-même dispose d'une interface de requête, vous pouvez l'utiliser, mais la solution sera très spécifique à l'environnement et peu fiable.

22
Sunny Milenov

J'ai aimé le http://ipify.org . Ils fournissent même du code Python pour utiliser leur 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
32
mario1ua

Python3, n'utilisant que la bibliothèque standard

Comme mentionné précédemment, il est impossible de contourner un service externe de quelque sorte afin de découvrir l'adresse IP externe de votre routeur.

Voici comment procéder avec python3, en n'utilisant rien d'autre que la bibliothèque standard:

import urllib.request

external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')

print(external_ip)
25
Serge Stroobandt

Vous devez utiliser le protocole UPnP pour interroger votre routeur à propos de ces informations. Surtout, cela ne repose pas sur un service externe, ce que toutes les autres réponses à cette question semblent suggérer.

Il existe une bibliothèque Python appelée miniupnp qui peut le faire, voir par exemple. miniupnpc/testupnpigd.py .

pip install miniupnpc

Sur la base de leur exemple, vous devriez pouvoir faire quelque chose comme ceci:

import miniupnpc

u = miniupnpc.UPnP()
u.discoverdelay = 200
u.discover()
u.selectigd()
print('external ip address: {}'.format(u.externalipaddress()))
14
Vegard

Si vous pensez que la source externe est trop peu fiable, vous pouvez regrouper quelques services différents. Pour la plupart des pages de recherche ip, ils vous obligent à balayer le code HTML, mais quelques-uns d'entre eux ont créé des pages minces pour des scripts comme le vôtre, afin de réduire le nombre de hits sur leurs sites:

6
Thomas Ahle

A mon avis, la solution la plus simple est de 

    f = requests.request('GET', 'http://myip.dnsomatic.com')
    ip = f.text

C'est tout.

3
Jit9

J'ai essayé la plupart des autres réponses à cette question ici et suis arrivé à constater que la plupart des services utilisés étaient périmés sauf un.

Voici un script qui devrait faire l'affaire et ne télécharger qu'une quantité minimale d'informations:

#!/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 __== '__main__':
  print( get_external_ip() )
2
Christian Jensen
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"
2
Nikita Rovda

La solution de travail la plus simple (sans python) à laquelle je peux penser est

wget -q -O- icanhazip.com

J'aimerais ajouter une très courte solution Python3 qui utilise l'API JSON de 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'])

Vous pouvez bien sûr ajouter des vérifications d'erreur, une condition de délai d'attente et une certaine commodité:

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

Si la machine est un pare-feu, votre solution est très judicieuse: l’autre solution consiste à interroger le pare-feu, ce qui dépend en fin de compte du type de pare-feu (si possible).

1
jldupont

Travailler avec Python 2.7 . 6 et 2.7.13 

import urllib2  
req = urllib2.Request('http://icanhazip.com', data=None)  
response = urllib2.urlopen(req, timeout=5)  
print(response.read())
1
user3526918
In [1]: import stun

stun.get_ip_info()
('Restric NAT', 'xx.xx.xx.xx', 55320)
1
enthus1ast

Si vous écrivez simplement pour vous-même et non pour une application généralisée, vous pourrez peut-être trouver l'adresse sur la page de configuration de votre routeur, puis la récupérer dans le fichier HTML de cette page. Cela a bien fonctionné pour moi avec mon routeur SMC. Une lecture et une recherche simple dans RE et je l'ai trouvée.

Mon intérêt particulier à cet égard était de me faire savoir l'adresse IP de mon domicile lorsque je n'étais pas chez moi, afin de pouvoir rentrer via VNC. Quelques lignes supplémentaires de Python stockent l'adresse dans Dropbox pour un accès extérieur, et m'envoient même un courrier électronique en cas de changement. Je l'ai prévu au démarrage et une fois par heure ensuite.

0
Bruce

Si vous ne souhaitez pas utiliser de services externes (sites Web IP, etc.), vous pouvez utiliser le protocole UPnP .

Nous utilisons pour cela une simple bibliothèque de clients UPnP ( https://github.com/flyte/upnpclient ).

Installer:

pip installer upnpclient

Code simple:

import upnpclient

devices = upnpclient.discover()

if(len(devices) > 0):
    externalIP = devices[0].WANIPConn1.GetExternalIPAddress()
    print(externalIP)
else:
    print('No Connected network interface detected')

Code complet (pour obtenir plus d'informations mentionnées dans le fichier readme de 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'}
0
Eli

Voici un autre script alternatif.

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

EDIT: N'oubliez pas d'importer httplib et json

0
dr4ke616

Il existe quelques autres moyens qui ne dépendent pas de la vérification par Python d’un site Web externe, mais le système d’exploitation peut le faire. Votre principal problème ici est que même si vous n’utilisiez pas Python, si vous utilisiez la ligne de commande, aucune commande "intégrée" ne peut tout simplement vous indiquer l’adresse IP (WAN) externe. Des commandes telles que "ip addr show" et "ifconfig -a" vous indiquent l'adresse IP du serveur sur le réseau. Seul le routeur détient réellement l'IP externe. Cependant, il existe des moyens de trouver l'adresse IP externe (IP WAN) à partir de la ligne de commande. 

Ces exemples sont:

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

Par conséquent, le code python serait:

import os
ip = os.popen('wget -qO- http://ipecho.net/plain ; echo').readlines(-1)[0].strip()
print ip

OR

import os
iN, out, err = os.popen3('curl ipinfo.io/ip')
iN.close() ; err.close()
ip = out.read().strip()
print ip

OR

import os
ip = os.popen('Dig +short myip.opendns.com @resolver1.opendns.com').readlines(-1)[0].strip()
print ip

Ou bien, branchez l'un des exemples ci-dessus dans une commande telle que os.popen, os.popen2, os.popen3 ou os.system.

0
PyTis

Comme Sunny l'a suggéré, il n'est généralement pas possible d'obtenir une adresse IP externe dans un réseau sans l'aide de services externes. Consultez le tutoriel suivant qui couvre exactement la même chose. Je suppose que cela fonctionne pour Python 2.5.X. http://codetempo.com/programming/python/monitoring-ip-addresses-of-your-computer-start-up-script-on-linux-ubuntu

Il dit que ce tutoriel est pour Linux mais fonctionne aussi pour d'autres plateformes avec python.

0
Microkernel

Aussi simple que d'exécuter ceci en Python3:

import os

externalIP  = os.popen('curl -s ifconfig.me').readline()
print(externalIP)
0
JavDomGom

Utilisez request module:

import requests

myip = requests.get('https://www.wikipedia.org').headers['X-Client-IP']

print("\n[+] Public IP: "+myip)
0
J0KER11

Utilisez ce script:

import urllib, json

data = json.loads(urllib.urlopen("http://ip.jsontest.com/").read())
print data["ip"]

Sans json:

import urllib, re

data = re.search('"([0-9.]*)"', urllib.urlopen("http://ip.jsontest.com/").read()).group(1)
print data
0
A-312
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]

c'est un court extrait que j'avais écrit pour un autre programme. Le truc était de trouver un site Web assez simple pour que disséquer le code HTML ne soit pas une douleur.

0
Malcolm Boyd

Juste comme une alternative. Voici un script vous pouvez essayer.

0
ghostdog74