114

正在寻找一种更好的方法来获取机器当前的外部 IP #...以下工作,但宁愿不依赖外部站点来收集信息...我仅限于使用与 Mac OS 捆绑的标准 Python 2.5.1 库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)
4

29 回答 29

135

我喜欢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').content.decode('utf8')
print('My public IP address is: {}'.format(ip))
于 2016-03-24T16:44:21.530 回答
78

Python3,只使用标准库

如前所述,可以使用ident.me 之类的外部服务来发现路由器的外部 IP 地址。

以下是它是如何完成的python3,只使用标准库:

from urllib.request import urlopen

external_ip = urlopen('https://ident.me').read().decode('ascii')

print(external_ip)

这可以根据可用性和客户端偏好返回 IPv4 或 IPv6;仅对 IPv4使用https://v4.ident.me ,仅对 IPv6 使用https://v6.ident.me

于 2017-01-02T20:20:11.253 回答
44

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

于 2010-02-22T14:41:19.480 回答
35

您应该使用UPnP 协议来查询您的路由器以获取此信息。最重要的是,这不依赖于外部服务,这个问题的所有其他答案似乎都暗示了这一点。

有一个名为 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()))
于 2016-12-29T18:08:29.690 回答
27

我更喜欢这个 Amazon AWS 端点:

import requests
ip = requests.get('https://checkip.amazonaws.com').text.strip()
于 2019-08-20T18:00:02.573 回答
10

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

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

就这样。

于 2015-06-27T18:48:12.170 回答
8

尝试:

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

希望这会有所帮助

于 2020-08-07T18:15:34.887 回答
7

使用请求模块:

import requests

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

print("\n[+] Public IP: "+myip)
于 2019-02-08T02:16:22.727 回答
7

就像在 Python3 中运行它一样简单:

import os

externalIP  = os.popen('curl -s ifconfig.me').readline()
print(externalIP)
于 2019-03-02T11:21:45.287 回答
6

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

于 2010-02-22T14:52:17.627 回答
6

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

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

安装

点安装 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'}
于 2018-11-25T09:55:17.010 回答
4

还有一些其他方法不依赖 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 等命令中。

PS您可以使用“pip3 install pytis”并使用/查看用Python编写的“getip”程序。你也可以在这里找到它的代码:https ://github.com/PyTis/PyTis/blob/development/src/pytis/getip.py

于 2018-09-19T18:14:56.537 回答
4

我使用 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))
于 2021-01-04T15:00:22.830 回答
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() )
于 2013-06-05T23:18:58.930 回答
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"
于 2017-03-31T04:39:50.397 回答
2

仅限 Linux 的解决方案。

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

像这样的东西,(假设'dig/drill'正在操作系统上工作)

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

对于 Arch 用户,请将 'dig' 替换为 'drill'。

于 2019-08-05T14:51:39.003 回答
1

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

于 2010-02-22T14:39:45.223 回答
1
In [1]: import stun

stun.get_ip_info()
('Restric NAT', 'xx.xx.xx.xx', 55320)
于 2014-03-26T22:10:12.707 回答
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
于 2014-05-09T10:39:25.977 回答
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())
于 2018-03-26T17:40:36.883 回答
1

我喜欢Sergiy Ostrovsky 的回答,但我认为现在有一种更整洁的方法可以做到这一点。

  1. 安装ipify库。
pip install ipify
  1. 在 Python 程序中导入并使用该库。
import ipify
ip = ipify.get_ip()
于 2021-05-26T20:38:23.203 回答
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 不是一件痛苦的事。

于 2013-02-05T03:23:00.540 回答
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

于 2014-01-19T12:59:44.740 回答
0

如果您只是为自己编写而不是为通用应用程序编写,您可能能够在路由器的设置页面上找到地址,然后从该页面的 html 中抓取它。这对我的 SMC 路由器很有效。一次阅读和一次简单的 RE 搜索,我找到了。

我这样做的特别兴趣是在我不在家时让我知道我的家庭 IP 地址,这样我就可以通过 VNC 回来。再多几行 Python 代码将地址存储在 Dropbox 中以供外部访问,如果它看到更改,甚至会通过电子邮件发送给我。我已经安排它在启动时发生,之后每小时一次。

于 2014-05-04T21:39:18.440 回答
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
于 2016-02-29T18:37:05.040 回答
0

import os public_ip = os.system("inxi -i |grep 'WAN IP'") print(public_ip)

于 2021-08-18T18:55:42.300 回答
0

不幸的是,如果不咨询互联网上的计算机,就无法获取您的外部 IP 地址。充其量,您可以获得您网卡的本地网络 IP 地址(可能是 192.16..地址)。

您可以使用该whatismyip模块获取外部 IP 地址。它在 Python 3 标准库之外没有依赖项。它连接到公共 STUN 服务器和 what-is-my-ip 网站以查找 IPv4 或 IPv6 地址。跑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'
于 2022-02-21T01:41:08.487 回答
-2

如果您对点击任何 url 获取公共 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 发送到我的服务器。

希望这会有所帮助

于 2020-01-14T10:53:14.663 回答
-3
import os
externalIp = os.popen("ipconfig").read().split(":")[15][1:14]

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

于 2021-01-03T17:12:01.223 回答