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

cit*_*cit 58 python standard-library

寻找一种更好的方法来获取机器当前的外部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)
Run Code Online (Sandbox Code Playgroud)

mar*_*1ua 57

我喜欢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
Run Code Online (Sandbox Code Playgroud)


Ser*_*ndt 35

Python3,除了标准库之外别无其他

如前所述,为了发现路由器的外部IP地址,无法使用某种类型的外部服务.

以下是python3使用标准库以外的其他方法:

import urllib.request

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

print(external_ip)
Run Code Online (Sandbox Code Playgroud)

  • @Oliver按照你的建议,我测试了`api.ipify.org`和`ident.me`在欧洲这里,`ident.me`大约比`api.ipify.org`快三倍我知道你位于在加拿大。 (3认同)
  • 尽管OP适用于python 2,但我认为这应该是python 3的公认答案,因为它不使用任何第三方库。但是请注意,https://ident.me(以及其他类似https://ipv4bot.whatismyipaddress.com的请求)所花的时间大约是https://api.ipify.org或https要求的时间的“两倍”: //ipinfo.io/ip,使用与此答案相同的代码。我发现的最快和最简单的响应(在六个响应中)是api.ipify.org。 (2认同)
  • 请注意,当我从主机使用“ident.me”时,它返回“IPv6”地址,而其他地址则从同一位置返回“IPv4”地址。 (2认同)

Sun*_*nov 27

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


Veg*_*ard 21

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

有一个名为miniupnp的Python库可以做到这一点,参见例如miniupnpc/testupnpigd.py.

pip install miniupnpc
Run Code Online (Sandbox Code Playgroud)

基于他们的例子你应该能够做这样的事情:

import miniupnpc

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


Max*_*ysh 21

我更喜欢这个 Amazon AWS 端点:

import requests
ip = requests.get('https://checkip.amazonaws.com').text.strip()
Run Code Online (Sandbox Code Playgroud)


小智 11

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

import requests
f = requests.request('GET', 'http://myip.dnsomatic.com')
ip = f.text
Run Code Online (Sandbox Code Playgroud)

就这样。

  • 可能值得一提的是您需要“导入请求”。见 https://pypi.python.org/pypi/requests (2认同)

Jav*_*Gom 8

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

import os

externalIP  = os.popen('curl -s ifconfig.me').readline()
print(externalIP)
Run Code Online (Sandbox Code Playgroud)

  • 这需要安装curl (2认同)

Tho*_*hle 6

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


Eli*_*Eli 6

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

为此,我们使用一个简单的 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')
Run Code Online (Sandbox Code Playgroud)

完整代码(获取 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'}
Run Code Online (Sandbox Code Playgroud)


PyT*_*Tis 5

还有一些其他方法不依赖于 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
Run Code Online (Sandbox Code Playgroud)

因此,Python 代码将是:

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

或者

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

或者

import os
ip = os.popen('dig +short myip.opendns.com @resolver1.opendns.com').readlines(-1)[0].strip()
print ip
Run Code Online (Sandbox Code Playgroud)

或者,将上面的任何其他示例插入到 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


小智 5

使用请求模块:

import requests

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

print("\n[+] Public IP: "+myip)
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢用这个来完成简单的任务。不过不需要下载整个页面,我们只需要标题。为此,我建议改用“requests.head”。效率更高。 (3认同)

NUA*_*CHE 5

尝试:

import requests 
ip = requests.get('http://ipinfo.io/json').json()['ip']
Run Code Online (Sandbox Code Playgroud)

希望这有帮助


小智 5

我使用 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))
Run Code Online (Sandbox Code Playgroud)