Quick and Dirty GeoIP Lookup Function in Python
I found a free GeoIP lookup service, that happens to have a simple API for getting the result in XML: http://api.hostip.info/?ip=65.34.176.69. The returned XML looks like this:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<HostipLookupResultSet version="1.0.0" xmlns="http://www.hostip.info/api" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hostip.info/api/hostip-1.0.0.xsd">
<gml:description<This is the Hostip Lookup Service</gml:description>
<gml:name>hostip</gml:name>
<gml:boundedBy>
<gml:Null>inapplicable</gml:Null>
</gml:boundedBy>
<gml:featureMember>
<Hostip>
<gml:name>Miami, FL</gml:name>
<countryName>UNITED STATES</countryName>
<countryAbbrev>US</countryAbbrev>
<!-- Co-ordinates are available as lng,lat -->
<ipLocation>
<gml:PointProperty>
<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:coordinates>-80.2108,25.7757</gml:coordinates>
</gml:Point>
</gml:PointProperty>
</ipLocation>
</Hostip>
</gml:featureMember>
</HostipLookupResultSet>
I had never done anything with XML in python so I figured I would write a function to wrap the API call. A few google searches led me to minidom and the rest was cake. The function takes in an IP address (string) and returns a dictionary with the geo information. I am a python noob and this code feels a little sketchy to me, so any feedback is more than welcome!
import urllib
from xml.dom import minidom
GEO_IP_LOOKUP_URL = 'http://api.hostip.info/?ip=%s'
GML_NS = 'http://www.opengis.net/gml'
def geo_ip_lookup(ip_address):
"""
Look up the geo information based on the IP address passed in
"""
dom = minidom.parse(urllib.urlopen(GEO_IP_LOOKUP_URL % ip_address))
elem = dom.getElementsByTagName('Hostip')[0]
location = elem.getElementsByTagNameNS(GML_NS, 'name')[0].firstChild.data.partition(',')
try:
latlong = elem.getElementsByTagNameNS(GML_NS, 'coordinates')[0].firstChild.data.partition(',')
except:
# lat/long isnt always returned
latlong = None
return {
'country_code': elem.getElementsByTagName('countryAbbrev')[0].firstChild.data,
'country_name': elem.getElementsByTagName('countryName')[0].firstChild.data,
'locality': location[0].strip(),
'region': location[2].strip(),
'longitude': latlong[0].strip() if latlong else '',
'latitude': latlong[2].strip() if latlong else ''
}
Calling it from the interpreter:
>>> geo_ip_lookup('65.34.176.69')
{'locality': u'Miami', 'region': u'FL', 'longitude': u'-80.2108', 'latitude': u'25.7757', 'country_code': u'US', 'country_name': u'UNITED STATES'}
>>>
blog comments powered by Disqus