使用Python获取计算机的外部IP地址

时间:2010-02-22 14:36:41

标签: python standard-library

寻找更好的方法来获取机器当前的外部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)

27 个答案:

答案 0 :(得分:41)

我喜欢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

答案 1 :(得分:27)

Python3,只使用标准库

如前所述,为了发现路由器的外部IP地址,我们无法使用某些类型的external service来解决这个问题。

以下是使用for(var i = 0; i < 12; i++) { var d = new Date(1993,i,3); var n = d.toLocaleDateString(); document.getElementById("demo").innerHTML += n + "<br>"; } 3.1.1993 3.2.1993 3.3.1993 3.4.1993 3.5.1993 3.6.1993 3.7.1993 3.8.1993 3.9.1993 2.10.1993 3.11.1993 3.12.1993 完成工作的方式,除了the standard library:

之外别无其他
python3

答案 2 :(得分:24)

如果你在获得外部IP的路由器后面,我恐怕你别无选择,只能像你一样使用外部服务。如果路由器本身有一些查询接口,你可以使用它,但解决方案将是非常环境和不可靠的。

答案 3 :(得分:17)

您应该使用UPnP protocol在路由器中查询此信息。最重要的是,这不依赖于外部服务,而这个问题的所有其他答案似乎都表明了这一点。

有一个名为miniupnp的Python库可以做到这一点,参见例如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()))

答案 4 :(得分:6)

如果您认为外部资源太不可靠,您可以汇集一些不同的服务。对于大多数ip查找页面,他们要求你抓取html,但其中一些已经创建了像你这样的脚本的瘦页面 - 这样他们就可以减少他们网站上的点击量:

答案 5 :(得分:5)

尝试:

import requests 
ip = requests.get('http://ipinfo.io/json').json()['ip']

希望这会有所帮助

答案 6 :(得分:4)

我更喜欢此Amazon AWS终端节点:

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

答案 7 :(得分:3)

在我看来,最简单的解决方案是

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

多数人。

答案 8 :(得分:2)

我在这个问题上尝试了大部分其他答案,然后发现大多数使用的服务都已解散,除了一个。

这是一个应该做的技巧,只下载最少量的信息:

#!/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 :(得分:2)

我使用 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))

答案 10 :(得分:2)

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"

答案 11 :(得分:1)

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

答案 12 :(得分:1)

与在Python3中运行一样简单:

import os

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

答案 13 :(得分:1)

如果机器是防火墙,那么你的解决方案是一个非常明智的解决方案:能够查询防火墙的替代方案最终依赖于防火墙的类型(如果可能的话)。

答案 14 :(得分:1)

我能想到的最简单(非python)工作解决方案是

wget -q -O- icanhazip.com

我想添加一个非常简短的Python3解决方案,它使用了http://hostip.info的JSON API。

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

答案 15 :(得分:1)

In [1]: import stun

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

答案 16 :(得分:0)

使用此脚本:

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

答案 17 :(得分:0)

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并不是一件痛苦的事。

答案 18 :(得分:0)

还有其他一些不依赖Python检查外部网站的方法,但是OS可以。这里的主要问题是,即使您没有使用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

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

或者,将上述任何其他示例插入到os.popen,os.popen2,os.popen3或os.system之类的命令中。

答案 19 :(得分:0)

如果您不想使用外部服务(IP网站等),则可以使用UPnP Protocol

为此,我们使用一个简单的UPnP客户端库(https://github.com/flyte/upnpclient

安装

  

pip安装upnpclient

简单代码

import upnpclient

devices = upnpclient.discover()

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

完整代码(以获取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'}

答案 20 :(得分:0)

使用请求模块:

import requests

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

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

答案 21 :(得分:0)

仅Linux解决方案。

在Linux系统上,可以使用Python在Shell上执行命令。我认为这可能会对某人有所帮助。

这样的事情(假设“ dig”在操作系统上起作用)

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

答案 22 :(得分:0)

如果您只为自己编写而不是为通用应用程序编写,您可以在路由器的设置页面上找到该地址,然后从该页面的HTML中删除它。使用我的SMC路由器,这对我来说很好。一次阅读,一次简单的RE搜索,我就找到了。

我特别感兴趣的是当我不在家时让我知道我的家庭IP地址,所以我可以通过VNC回来。还有几行Python将地址存储在Dropbox中以供外部访问,如果发现更改,甚至会通过电子邮件发送给我。我预定它会在启动时发生,并在此后一小时发生。

答案 23 :(得分:0)

如果您不希望点击任何网址来获取公共ip,我认为以下代码可以帮助您使用计算机的python获取公共ip

import os
externalIP  = os.popen("ifconfig | grep 'inet' | cut -d: -f2 | awk '{print $2}' | sed -n 3p").readline()
print externalIP

sed -n 3p线路因用于连接设备的网络而异。

我面临着同样的问题,我需要iot设备的公共ip,它正在冲击我的服务器。但是,公共IP在ifconfig命令中是完全不同的,而IP是我从请求对象进入服务器的。之后,我在请求中添加了额外的参数,以将设备的ip发送到服务器。

希望这会有所帮助

答案 24 :(得分:0)

这是另一个替代脚本。

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

答案 25 :(得分:0)

我喜欢Sergiy Ostrovsky's answer,但我认为现在有一种更简洁的方法可以做到这一点。

  1. 安装 ipify 库。
pip install ipify
  1. 在您的 Python 程序中导入和使用该库。
import ipify
ip = ipify.get_ip()

答案 26 :(得分:-3)

import os
externalIp = os.popen("ipconfig").read().split(":")[15][1:14]

某些数字可能需要更改,但这对我有用