Reputation: 8661
I am developing a project, that needs to store user location in my data base. I got the public IP address of that user. But I am unable to get the user location. I have tried several ways (from StackOverflow) but I didn't find any hint. Like the below
url = urllib.urlopen("http://api.hostip.info/get_html.php?ip=%s&position=true" % ip)
data = re.compile('^[^\(]+\(|\)$').sub('', url.read())
print data
but I am getting the result as
Unknown Country?) (XX)
City: (Unknown City?)
another way:
import urllib
response = urllib.urlopen("http://api.hostip.info/get_html.php?ip={}&position=true".format(ip)).read()
print(response)
but the result is
Country: (Unknown Country?) (XX)
City: (Unknown City?)
Latitude:
Longitude:
IP: 115.xxx.xxx.xx
Any help would be appreciated!
Upvotes: 61
Views: 172945
Reputation: 798
for python-3.x
def print_ip_info(addr=None):
from urllib.request import urlopen
import json
if addr is None:
url = 'https://ipinfo.io/json'
else:
url = 'https://ipinfo.io/' + addr + '/json'
# if res==None, check your internet connection
res = urlopen(url)
data = json.load(res)
for attr in data.keys():
# print the data line by line
print(attr, ' '*13 + '\t->\t', data[attr])
Upvotes: 24
Reputation: 5193
Try with pygeoip (It looks deprecated)
~$ ping stackoverflow.com
PING stackoverflow.com (198.252.206.16) 56(84) bytes of data.
>>> import pygeoip
>>> GEOIP = pygeoip.GeoIP("/absolute_path/GeoIP.dat", pygeoip.MEMORY_CACHE)
>>> GEOIP.country_name_by_addr(ip)
'United States'
GeoIP.data is available here
Upvotes: 19
Reputation: 19
import urllib.request
import json
ips = ['x.x.x.x', 'x.x.x.x','x.x.x.x']
for ip in ips:
with urllib.request.urlopen("https://geolocation-db.com/jsonp/"+ip) as url:
data = url.read().decode()
data = data.split("(")[1].strip(")")
print(data)
Upvotes: 1
Reputation: 2238
You can do that using ipinfo's api
first go to ipinfo.io and sign up. You'll get a access token, copy it, now do pip install ipinfo
now you can type this sample code:
>>> import ipinfo
>>> handler = ipinfo.getHandler(access_token)
>>> d = handler.getDetails(ip_address)
>>> d.city
or if you'll directly do d.details
it will return a dictionary and you could use it as a dictionary too, it would have all things like ip address, city, country, state etc. you can also get them using like this d.country
or for location d.loc
, for city, as i wrote, d.city
Upvotes: 3
Reputation: 595
nmap --script ip-geolocation-geoplugin <target>
Script Output
| ip-geolocation-geoplugin:
| coordinates: 39.4208984375, -74.497703552246
|_location: New Jersey, United States
https://nmap.org/nsedoc/scripts/ip-geolocation-geoplugin.html
Upvotes: 0
Reputation: 389
Thanks for all the solutions and workarounds! However, I was not able to use all of the above methods.
Here is what worked for me:
import requests
response = requests.get("https://geolocation-db.com/json/39.110.142.79&position=true").json()
This method seemed simple and easy to use. (I needed to work with a dictionary response...)
In the future, the "geolocation-db.com" might become unavailable, so alternative sources might be required!
Upvotes: 23
Reputation: 12953
You can use the services of https://geolocation-db.com IPv4 and IPv6 are supported. Either a JSON-object or JSONP callback function is returned.
Python 2:
import urllib
import json
url = "https://geolocation-db.com/json"
response = urllib.urlopen(url)
data = json.loads(response.read())
print data
Python 3:
import urllib.request
import json
with urllib.request.urlopen("https://geolocation-db.com/json") as url:
data = json.loads(url.read().decode())
print(data)
A python 3 jsonp example:
import urllib.request
import json
with urllib.request.urlopen("https://geolocation-db.com/jsonp/8.8.8.8") as url:
data = url.read().decode()
data = data.split("(")[1].strip(")")
print(data)
Upvotes: 12
Reputation: 127
https://github.com/airakesh/BeautifulSoupRecipes/blob/master/geoip.py
# Get Geolocation(Country) and hostname by passing a file having a bunch of IP addresses as the argument from the command line. Example- python GeoIP.py path-to-file-containing-IP addresses:
https://github.com/airakesh/BeautifulSoupRecipes/blob/master/sample_ips.txt
import re
import os
import sys
import subprocess
import socket
# Input file argument
ips_file = sys.argv[1]
# The regular expression for validating an IP-address
pattern = '''^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)'''
def getGeoHost():
fp = open(ips_file, 'rb')
for line in fp:
line = line.strip()
addr = line.decode('utf-8')
regex = re.compile(pattern)
match = regex.match(addr)
# Get hostname by IP address
try:
host = socket.gethostbyaddr(addr)
hostname = host[0]
# Print Unknown no hostname is available
except:
hostname = 'Unknown'
# Get geolocation by IP address
get_geo_cmd = 'geoiplookup ' + addr
geo_str = subprocess.check_output(get_geo_cmd, shell=True)
geo = geo_str.decode('utf-8')
# Match country name pattern
geo_pattern = '''^(GeoIP Country Edition: ([A-Z]{2})\, (.*))'''
geo_regex = re.compile(geo_pattern)
country_match = re.match(geo_pattern, geo)
# Check country name is available and if not, print 'Unknown'
if country_match != '' and geo_pattern:
try:
country = country_match.group(3)
except:
country = 'Unknown'
# Clubbing together in format 'IP|Country|Hostname' data
geo_hostname = addr + ' | ' + country + ' | ' + hostname
print geo_hostname
if __name__ == "__main__":
ips_detail_list = getGeoHost()
Upvotes: 2
Reputation: 141
I found ipinfo offering the best service and providing free API usage for up to 50k calls per month - see 'Rate Limits' here:
import ipinfo
access_token = '123456789abc'
handler = ipinfo.getHandler(access_token)
ip_address = '216.239.36.21'
details = handler.getDetails(ip_address)
details.city
'Mountain View'
details.country
'US'
details.loc
'37.3861,-122.0840'
Upvotes: 6
Reputation: 142
Assuming that you got the ip address already, you can try to use the IP2Location Python Library to get the user location. A sample code is like this:
import os
import IP2Location
database = IP2Location.IP2Location(os.path.join("data", "IPV4-COUNTRY.BIN"))
rec = database.get_all(ip)
print(rec.country_short)
print(rec.country_long)
print(rec.region)
print(rec.city)
print(rec.isp)
print(rec.latitude)
print(rec.longitude)
print(rec.domain)
print(rec.zipcode)
print(rec.timezone)
print(rec.netspeed)
print(rec.idd_code)
print(rec.area_code)
print(rec.weather_code)
print(rec.weather_name)
print(rec.mcc)
print(rec.mnc)
print(rec.mobile_brand)
print(rec.elevation)
print(rec.usage_type)
Depends on your requirement, for example if you want to get the user's country name and region name, you can do this:
import os
import IP2Location
database = IP2Location.IP2Location(os.path.join("data", "IPV4-COUNTRY.BIN"))
rec = database.get_all(ip)
user_country = rec.country_long
user_region = rec.region
For more details, you can visit here: IP2Location Python library
Github link: IP2Location Python library Github
Upvotes: 11
Reputation: 24089
requirements:
sudo add-apt-repository ppa:maxmind/ppa
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
sudo pip install geoip2
geoip database:
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar xvfz GeoLite2-City.tar.gz
example for nginx access logs:
python -c 'import geoip2.database
reader = geoip2.database.Reader("./GeoLite2-City/GeoLite2-City.mmdb")
for line in open("/var/log/nginx/access.log').readlines():
response = reader.city(line.split(" ")[0])
print(dir(response))
'
related:
Upvotes: 4
Reputation: 1712
One of the simplest methods for getting the IP address as well as the location in detail is to use http://ipinfo.io
import re
import json
from urllib2 import urlopen
url = 'http://ipinfo.io/json'
response = urlopen(url)
data = json.load(response)
IP=data['ip']
org=data['org']
city = data['city']
country=data['country']
region=data['region']
print 'Your IP detail\n '
print 'IP : {4} \nRegion : {1} \nCountry : {2} \nCity : {3} \nOrg : {0}'.format(org,region,country,city,IP)
Upvotes: 48
Reputation: 8786
It ultimately depends on how you get your computers IP address. If you are on a VPN or another private network, just getting the local IP address will return nothing, like you are seeing now. In this case you have to get the public IP address like so:
url = 'http://api.hostip.info/get_json.php'
info = json.loads(urllib.urlopen(url).read())
ip = info['ip']
Here is my full code for getting all the information that you are seeking (I used freegeoip.net):
import urllib
import json
url = 'http://api.hostip.info/get_json.php'
info = json.loads(urllib.urlopen(url).read())
ip = info['ip']
urlFoLaction = "http://www.freegeoip.net/json/{0}".format(ip)
locationInfo = json.loads(urllib.urlopen(urlFoLaction).read())
print 'Country: ' + locationInfo['country_name']
print 'City: ' + locationInfo['city']
print ''
print 'Latitude: ' + str(locationInfo['latitude'])
print 'Longitude: ' + str(locationInfo['longitude'])
print 'IP: ' + str(locationInfo['ip'])
Upvotes: 3
Reputation: 2246
I'm doing this same thing on own server. Get an API key from http://ipinfodb.com/register.php and try:
import requests
ipdb = "http://api.ipinfodb.com/v3/ip-city/?key=<your api key>&ip="
ip_address = function_to_get_ip_address()
location = " ".join(str(requests.get(ipdb+ip_address).text).split(";")[4:7])
The value of location
will be COUNTRY REGION CITY
.
Keep in mind that IP addresses are not precise geo-locators. Especially when accessing your website from a mobile device, you'll see that the location of the IP address to be maybe 100 miles away from the physical location of the user.
Upvotes: 3