How to look-up Latitude/Longitude from list of IP addresses quickly in Python?

Viewed 918

I currently have a column of IP addresses that I'd like to concat with columns for corresponding latitude/longitude.

I'm currently using the following approach but it is super slow:

def getting_ip(row,latlong):
    url = r'https://freegeoip.app/json/'+row
    headers = {
        'accept': "application/json",
        'content-type': "application/json"
        }
    response = requests.request("GET", url, headers=headers)
    respond = json.loads(response.text)
    if respond[latlong]:
      return respond[latlong]
    else:
      return None

df['Latitude'] = [getting_ip(i,'latitude') if i else None for i in df['IP']]
df['Longitude'] = [getting_ip(i,'longitude') if i else None for i in df['IP']]

Using .apply with the definition doesn't save me much time, either, I spend most of the time in getting the request back. Is there a free, easy way to get latitudes/longitudes from ip addresses (that doesn't expire after a few requests?).

3 Answers

Is there a free, easy way to get latitudes/longitudes from ip addresses (that doesn't expire after a few requests?)

Yes, there is. Even at free tier IPinfo allows for 50,000 requests/month and you can do bulk lookup aka batch IP geolocation lookup.

So, what you will need to do:

  1. Install the IPinfo Python Module with pip install ipinfo
  2. Get your token after you have signed up
  3. Create the list of IP addresses
  4. Do bulk IP geolocation lookup using the handler.getBatchDetails function
  5. Extract the 'Latitude' and 'Longitude' from the dictionary of dictionary.

For example:

# install with `pip install ipinfo`
import ipinfo
import pandas as pd

# initialize handler with access token
access_token = "insert_your_token_here"
handler = ipinfo.getHandler(access_token)

# declare the ip address list
# here I have generated the IP addresses randomly
ip_addresses = ['201.67.58.192', '178.192.207.98', '63.12.221.229', '1.141.33.104']


# do the IP address batch lookup
ip_data = handler.getBatchDetails(ip_addresses)

# this will contain your extracted data
ip_dict = {"IP Address": [], "Latitude": [], "Longitude": []}

# extract data from ip_data to ip_dict
for key, value in ip_data.items():
  ip_dict["IP Address"].append(key)
  ip_dict["Latitude"].append(value['latitude'])
  ip_dict["Longitude"].append(value['longitude'])

# convert ip_dict to dataframe
df = pd.DataFrame(ip_dict)

The DataFrame (df) will look something like this.

IP Address Latitude Longitude
0 201.67.58.192 -16.4708 -54.6356
1 178.192.207.98 46.5113 6.4985
2 63.12.221.229 39.0437 -77.4875
3 1.141.33.104 -37.814 144.963

For this, if you prefer python then I find these packages:

ip2geotools

ip2geotools which can extract latitude and longitude from the IP address.

ip2geotools is a simple tool for getting geolocation information on a given IP address from various geolocation databases. This package provides an API for several geolocation databases.

An example is below:

>>> response = DbIpCity.get('147.229.2.90', api_key='free')
>>> response.ip_address
'147.229.2.90'
>>> response.city
'Brno (Brno střed)'
>>> response.region
'South Moravian'
>>> response.country
'CZ'
>>> response.latitude
49.1926824
>>> response.longitude
16.6182105
>>> response.to_json()
'{"ip_address": "147.229.2.90", "city": "Brno (Brno střed)", "region": "South Moravian", "country": "CZ", "latitude": 49.1926824, "longitude": 16.6182105}'
>>> response.to_xml()
'<?xml version="1.0" encoding="UTF-8" ?><ip_location><ip_address>147.229.2.90</ip_address><city>Brno (Brno střed)</city><region>South Moravian</region><country>CZ</country><latitude>49.1926824</latitude><longitude>16.6182105</longitude></ip_location>'
>>> response.to_csv(',')
'147.229.2.90,Brno (Brno střed),South Moravian,CZ,49.1926824,16.6182105'

Geoip2

Another package also available geoip2 which is similar to this package but has asynchronous request handling support and separate database searching options.

You can look at their website for the sync and async web service example if you required that.

Ip2location

As this API is mostly paid I try to find a free version and I find this library called Ip2location Python, it gives you 30000 lookups for free in a month.

You can get latitude and longitude for the IP addresses by using IP2Location Python Library. For example,

import os
import IP2Location

database = IP2Location.IP2Location(os.path.join("data", "IP2LOCATION-LITE-DB5.BIN"))

rec = database.get_all("19.5.10.1")

print(rec.country_short)
print(rec.country_long)
print(rec.region)
print(rec.city)
print(rec.latitude)
print(rec.longitude)

The above example code used IP2Location LITE DB5 database. You can sign up and get the database for free at here: https://lite.ip2location.com/sign-up.

Related