マシンに現在の外部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)
外部IPを取得するルーターの背後にいる場合、他のオプションはないのではないかと思います。ルーター自体にクエリインターフェイスがある場合は、それを使用できますが、ソリューションは非常に環境固有で信頼性が低くなります。
前述のように、ルーターの外部IPアドレスを検出するために、- https://ident.me のような 外部サービス を使用できます。
以下にpython3
、 標準ライブラリ: のみを使用
import urllib.request
external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
print(external_ip)
PnPプロトコル を使用して、この情報をルーターに照会する必要があります。最も重要なことは、これは外部サービスに依存していないことであり、この質問に対する他のすべての回答が示唆しているようです。
Pythonこれを行うことができるminiupnpというライブラリがあります。たとえば、 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()))
外部ソースの信頼性が低すぎると思われる場合は、いくつかの異なるサービスをプールできます。ほとんどのIPルックアップページでは、htmlをスクレイピングする必要がありますが、あなたのようなスクリプト用の無駄のないページを作成したいくつかのサイトでは、サイトへのヒットを減らすこともできます。
私の意見では、最も簡単な解決策は
f = requests.request('GET', 'http://myip.dnsomatic.com')
ip = f.text
それで全部です。
Python外部Webサイトのチェックに依存しない他のいくつかの方法がありますが、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などのコマンドにプラグインします。
この質問に関する他の回答のほとんどをここで試したところ、使用したサービスのほとんどは1つを除いて機能していませんでした。
トリックを実行し、最小限の情報のみをダウンロードするスクリプトを次に示します。
#!/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() )
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"
外部サービス(IP Webサイトなど)を使用したくない場合は、 PnPプロトコル を使用できます。
それには、単純なUPnPクライアントライブラリを使用します( https://github.com/flyte/upnpclient )
インストール:
pip install 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 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'}
私が考えることができる最も単純な(Pythonではない)作業ソリューションは
wget -q -O- icanhazip.com
http://hostip.info のJSON APIを利用する非常に短いPython3ソリューションを追加したいと思います。
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
マシンがファイアウォールである場合、あなたのソリューションは非常に賢明なものです:ファイアウォールの種類に依存するファイアウォールを照会できる代替手段(可能な場合)。
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())
Python3でこれを実行するのと同じくらい簡単です:
import os
externalIP = os.popen('curl -s ifconfig.me').readline()
print(externalIP)
import requests
myip = requests.get('https://www.wikipedia.org').headers['X-Client-IP']
print("\n[+] Public IP: "+myip)
In [1]: import stun
stun.get_ip_info()
('Restric NAT', 'xx.xx.xx.xx', 55320)
一般化されたアプリケーションではなく自分用に書いている場合は、ルーターのセットアップページでアドレスを見つけて、そのページのhtmlからアドレスを取得できる場合があります。これは、私のSMCルーター。1回の読み取りと1回の簡単なRE検索でうまくいきました。
これを行うことに特に興味があったのは、外出中に自宅のIPアドレスを教えてくれたので、VNC経由で戻ることができました。さらに数行のPythonは外部アクセス用にアドレスをDropboxに保存し、変更があった場合はメールで通知します。起動時とその後1時間に1回実行するようにスケジュールしました。
別の代替スクリプトを次に示します。
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をインポートすることを忘れないでください
Sunnyが示唆したように、一般に、外部サービスからの助けなしにネットワーク内にある外部IPアドレスを取得することはできません。まったく同じことをカバーする次のチュートリアルをご覧ください。 Python 2.5.X. http://codetempo.com/programming/python/monitoring-ip-addresses-of-your-computer-start-up -script-on-linux-ubunt
チュートリアルはLinux向けですが、pythonでも他のプラットフォームで動作します。
このスクリプトを使用します。
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
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の分析が苦痛にならないように、十分にシンプルなWebサイトを見つけることでした。
Linuxのみのソリューション
Linuxシステムでは、Pythonを使用してシェルでコマンドを実行できます。誰かに役立つ可能性があると思います。
このようなもの(「Dig」がOSで動作していると仮定)
import os
command = '''Dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}'''
ip = os.system(command)
代わりとして。 スクリプト を試してみてください。
私はこのAmazon AWSエンドポイントを好みます:
import requests
ip = requests.get('https://checkip.amazonaws.com').text.strip()