How can I get the public IP using python2.7? Not private IP.
-
I'd agree with this post as a duplicate -- same answers anyway – Alvin May 25 '12 at 07:40
-
possible duplicate of [Finding a public facing IP address in Python?](http://stackoverflow.com/questions/166545/finding-a-public-facing-ip-address-in-python) – jfs Feb 24 '14 at 21:49
7 Answers
Currently there are several options:
- ip.42.pl
- jsonip.com
- httpbin.org
- ipify.org
Below are exact ways you can utilize each of the above.
ip.42.pl
from urllib2 import urlopen
my_ip = urlopen('http://ip.42.pl/raw').read()
This is the first option I have found. It is very convenient for scripts, you don't need JSON parsing here.
jsonip.com
from json import load
from urllib2 import urlopen
my_ip = load(urlopen('https://ipv4.jsonip.com'))['ip']
Seemingly the sole purpose of this domain is to return IP address in JSON.
httpbin.org
from json import load
from urllib2 import urlopen
my_ip = load(urlopen('http://httpbin.org/ip'))['origin']
httpbin.org is service I often recommend to junior developers to use for testing their scripts / applications.
ipify.org
from json import load
from urllib2 import urlopen
my_ip = load(urlopen('https://api.ipify.org/?format=json'))['ip']
Power of this service results from lack of limits (there is no rate limiting), infrastructure (placed on Heroku, with high availability in mind) and flexibility (works for both IPv4 and IPv6).
EDIT: Added httpbin.org to the list of available options.
EDIT: Added ipify.org thanks to kert's note.
-
3I like icanhazip.com, it's a whole website with just your raw IP; no need to add arrays, formats, etc. – anonymous Aug 09 '17 at 01:01
-
Just to add for ipify.org: With the url `https://api.ipify.org/?format=raw` you'll get the IP in plaintext, no JSON nonsense. – pepoluan Jul 17 '20 at 03:37
-
https://api.ident.me works too, please fallback to https://tnedi.me if you want to write a complete code example ;) – Pierre Carrier Feb 22 '22 at 22:35
I like the requests package with http://ip.42.pl/raw
import requests
requests.get('http://ip.42.pl/raw').text

- 1,129
- 12
- 12
With requests module
import requests
public_IP = requests.get("https://www.wikipedia.org").headers["X-Client-IP"]
print public_IP

- 414
- 4
- 3
-
1nice! :) i like this over pinging some random site. i want to say it's more fragile, but i guess it's a bigger name than some of the other sites. As long as they don't change how their headers operate... – digitalfoo Feb 24 '20 at 00:15
Try this:
import ipgetter
import requests
IP = ipgetter.myip()
url = 'http://freegeoip.net/json/'+IP
r = requests.get(url)
js = r.json()
print 'IP Adress: ' + js['ip']
print 'Country Code: ' + js['country_code']
print 'Country Name: ' + js['country_name']
print 'Region Code: ' + js['region_code']
print 'Region Name: ' + js['region_name']
print 'City Name: ' + js['city']
print 'Zip code: ' + js['zip_code']
print 'Time Zone: ' + js['time_zone']
print 'Latitude: ' + str(js['latitude'])
print 'Longitude: ' + str(js['longitude'])

- 2,125
- 1
- 16
- 17
-
1
-
ipgetter does not (yet) support IPv6, although IPv6 is already celebrating its twentieth birthday. :( – qräbnö Jun 06 '18 at 20:19
-
Dead as of 2022-01-24, try this: http://freegeoip.net/json/1.1.1.1 and it redirects to http://freegeoip.net/shutdown. – Contango Jan 24 '22 at 18:37
You can just do this:
import requests
print requests.get("http://ipecho.net/plain?").text
Produces:
XX.XX.XXX.XXX

- 26,989
- 16
- 82
- 98

- 31
- 5
in python 2.7 it's just a code of 2 lines.
>>> import requests
>>print requests.get("http://ipconfig.in/ip").text

- 179,855
- 19
- 132
- 245

- 11
- 1
-
1Please don't reply to duplicate questions. Mark them as duplicate. It makes SO more organized. – toliveira Apr 19 '20 at 23:37
-
This is a way not to have to make a call to the internet:
Please let me know if this doesn't work, then I can update the answer (it works for ~10 servers of mine)
from subprocess import check_output
out = check_output("/sbin/ifconfig | awk '/inet / { print $2 }' | sed 's/addr://'", shell=True)
[x for x in out.decode().split() if not x == "127.0.0.1" and
not (x.startswith("172") and x.endswith("0.1"))]
["x.x.x.x.x"]

- 20,643
- 17
- 103
- 160