Getting a machine's external IP address with Python

人盡茶涼 提交于 2019-12-27 16:40:52

问题


Looking for a better way to get a machines current external IP #... Below works, but would rather not rely on an outside site to gather the information ... I am restricted to using standard Python 2.5.1 libraries bundled with 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)

回答1:


If you are behind a router which obtains the external IP, I'm afraid you have no other option but to use external service like you do. If the router itself has some query interface, you can use it, but the solution will be very environment-specific and unreliable.




回答2:


I liked the http://ipify.org. They even provide Python code for using their 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



回答3:


Python3, using nothing else but the standard library

As mentioned before, one can use an external service like https://ident.me in order to discover the external IP address of your router.

Here is how it is done with python3, using nothing else but the standard library:

import urllib.request

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

print(external_ip)



回答4:


You should use the UPnP protocol to query your router for this information. Most importantly, this does not rely on an external service, which all the other answers to this question seem to suggest.

There's a Python library called miniupnp which can do this, see e.g. miniupnpc/testupnpigd.py.

pip install miniupnpc

Based on their example you should be able to do something like this:

import miniupnpc

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



回答5:


If you think and external source is too unreliable, you could pool a few different services. For most ip lookup pages they require you to scrape html, but a few of them that have created lean pages for scripts like yours - also so they can reduce the hits on their sites:

  • automation.whatismyip.com/n09230945.asp (Update: whatismyip has taken this service down)
  • whatismyip.org



回答6:


I prefer this Amazon AWS endpoint:

import requests
ip = requests.get('https://checkip.amazonaws.com').text.strip()



回答7:


In my opinion the simplest solution is

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

Thats all.




回答8:


I tried most of the other answers on this question here and came to find that most of the services used were defunct except one.

Here is a script that should do the trick and download only a minimal amount of information:

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



回答9:


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"



回答10:


There are a few other ways that do not rely on Python checking an external web site, however the OS can. Your primary issue here, is that even if you were not using Python, if you were using the command line, there are no "built-in" commands that can just simply tell you the external (WAN) IP. Commands such as "ip addr show" and "ifconfig -a" show you the server's IP address's within the network. Only the router actually holds the external IP. However, there are ways to find the external IP address (WAN IP) from the command line.

These examples are:

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

Therefore, the python code would be:

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

Or, plug any other of the examples above, into a command like os.popen, os.popen2, os.popen3, or os.system.




回答11:


Use requests module:

import requests

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

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



回答12:


As simple as running this in Python3:

import os

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



回答13:


If the machine is being a firewall then your solution is a very sensible one: the alternative being able to query the firewall which ends-up being very dependent on the type of firewall (if at all possible).




回答14:


The most simple (non python) working solution I can think of is

wget -q -O- icanhazip.com

I'd like to add a very short Python3 solution which makes use of the JSON API of 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'])

You can of course add some error checking, a timeout condition and some convenience:

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



回答15:


In [1]: import stun

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



回答16:


Working with Python 2.7.6 and 2.7.13

import urllib2  
req = urllib2.Request('http://icanhazip.com', data=None)  
response = urllib2.urlopen(req, timeout=5)  
print(response.read())



回答17:


If you don't want to use external services (IP websites, etc.) You can use the UPnP Protocol.

Do to that we use a simple UPnP client library (https://github.com/flyte/upnpclient)

Install:

pip install upnpclient

Simple Code:

import upnpclient

devices = upnpclient.discover()

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

Full Code (to get more information as mentioned in the github readme)

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



回答18:


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]

this is a short snippet I had written for another program. The trick was finding a simple enough website so that dissecting the html wasn't a pain.




回答19:


Here's another alternative script.

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: Don't forget to import httplib and json




回答20:


If you're just writing for yourself and not for a generalized application, you might be able to find the address on the setup page for your router and then scrape it from that page's html. This worked fine for me with my SMC router. One read and one simple RE search and I've found it.

My particular interest in doing this was to let me know my home IP address when I was away from home, so I could get back in via VNC. A few more lines of Python stores the address in Dropbox for outside access, and even emails me if it sees a change. I've scheduled it to happen on boot and once an hour thereafter.




回答21:


Use this script :

import urllib, json

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

Without json :

import urllib, re

data = re.search('"([0-9.]*)"', urllib.urlopen("http://ip.jsontest.com/").read()).group(1)
print data



回答22:


Linux only solution.

On Linux Systems, you can use Python to execute a command on the shell. I think it might help someone.

Something like this, (assuming 'dig' is working on the os)

import os
command = '''dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}'''
ip = os.system(command)


来源:https://stackoverflow.com/questions/2311510/getting-a-machines-external-ip-address-with-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!