ipinfodb.com provides a free service wich let you obtain geolocation info about any ip address. you can access this info parsing the content returned by this page.
the request must be done in this way
http://ipinfodb.com/ip_query.php?timezone=true&ip=204.236.220.71
UPDATE
The above url is not longer valid because to a New APIs are being introduced with API key. you must register in this site to get access to the info.
now you must use a url like this
http://api.ipinfodb.com/v2/ip_query.php?key=&ip=74.125.45.100&timezone=true
and the response look like this
<Response> <Ip>204.236.220.71</Ip> <Status>OK</Status> <CountryCode>US</CountryCode> <CountryName>United States</CountryName> <RegionCode>53</RegionCode> <RegionName>Washington</RegionName> <City>Seattle</City> <ZipPostalCode>98144</ZipPostalCode> <Latitude>47.5839</Latitude> <Longitude>-122.299</Longitude> <TimezoneName>America/Los_Angeles</TimezoneName> <Gmtoffset>-28800</Gmtoffset> <Isdst>0</Isdst> </Response>
Now using a TIdHTTP component you can get the result of the request to this page.
uses Classes, ComObj, Variants, IdHTTP, type TGeoInfo = record Status : string; CountryCode : string; CountryName : string; RegionCode : string; City : string; ZipPostalCode : string; Latitude : string; Longitude : string; TimezoneName : string; Gmtoffset : string; Isdst : string; end; const UrlGeoLookupInfo ='http://ipinfodb.com/ip_query.php?timezone=true&ip=%s'; UrlGeoLookupInfo2 ='http://backup.ipinfodb.com/ip_query.php?timezone=true&ip=%s'; //backup server procedure GetGeoInfo(const IpAddress : string;var GeoInfo :TGeoInfo); var lHTTP : TIdHTTP; lStream: TStringStream; XMLDoc : OleVariant; ANode : OleVariant; begin lHTTP := TIdHTTP.Create(nil); lStream := TStringStream.Create; try try lHTTP.Get(Format(UrlGeoLookupInfo,[IpAddress]), lStream); //get the request except lHTTP.Get(Format(UrlGeoLookupInfo2,[IpAddress]), lStream); //if something is wrong try using the backup server. end; lStream.Seek(0,0); XMLDoc := CreateOleObject('Msxml2.DOMDocument.6.0'); XMLDoc.async := false; XMLDoc.LoadXML(lStream.ReadString(lStream.Size)); XMLDoc.setProperty('SelectionLanguage','XPath');//use XPath to parse the xml result ANode:=XMLDoc.selectSingleNode('/Response/Status'); if not VarIsNull(ANode) then GeoInfo.Status:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/CountryCode'); if not VarIsNull(ANode) then GeoInfo.CountryCode:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/CountryName'); if not VarIsNull(ANode) then GeoInfo.CountryName:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/RegionCode'); if not VarIsNull(ANode) then GeoInfo.RegionCode:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/City'); if not VarIsNull(ANode) then GeoInfo.City:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/ZipPostalCode'); if not VarIsNull(ANode) then GeoInfo.ZipPostalCode:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/Latitude'); if not VarIsNull(ANode) then GeoInfo.Latitude:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/Longitude'); if not VarIsNull(ANode) then GeoInfo.Longitude:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/TimezoneName'); if not VarIsNull(ANode) then GeoInfo.TimezoneName:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/Gmtoffset'); if not VarIsNull(ANode) then GeoInfo.Gmtoffset:=ANode.Text; ANode:=XMLDoc.selectSingleNode('/Response/Isdst'); if not VarIsNull(ANode) then GeoInfo.Isdst:=ANode.Text; finally lHTTP.Free; lStream.Free; end; end;
November 14, 2010 at 12:07 am
Good to know!
Is it accurate? I guess I’ll have to try with my blog’s comments without a proper flag to see if it finds them …
November 14, 2010 at 10:37 am
François, check this link http://ipinfodb.com/ip_database.php
November 14, 2010 at 12:30 am
Thanks for the useful article and site link Rodrigo. Unfortunately, the code you posted will only work for a couple of days (until Nov 15). The site is moving to a new API that requires an API key and registration.
Best regards.
November 14, 2010 at 10:34 am
Don, i knew about the API change of the November 15, but I’m not sure which involves the request made using this page http://ipinfodb.com/ip_query.php?timezone=true&ip=, i hope not.
if your check this page http://ipinfodb.com/ip_location_api.php you can find several samples using the current API i wich is done in this way
http://api.ipinfodb.com/v2/ip_query.php?key=&ip=74.125.45.100&timezone=false
November 14, 2010 at 3:37 am
Why the double-slash (//) descendant operator search in stead of the single-slash (/) search prefix at the beginning of your XPath queries?
You know for sure that the Ip will be at /Response/Ip, so why have it search through the whole document using //Response/Ip ?
BTW: http://chris.photobooks.com/xml is a nice on-line way of checking your XPath queries.
BTW2: Nice list of XPath patterns: http://www.brainbell.com/tutors/XML/XML_Book_B/Basic_XPath_Patterns.htm
–jeroen
Via: http://www.tizag.com/xmlTutorial/xpathdescendant.php
November 14, 2010 at 10:50 am
Jeroen, thanks for you suggestions, for this particular case both methods works
using
ANode:=XMLDoc.selectSingleNode('//Response/Status');
or
ANode:=XMLDoc.selectSingleNode('/Response/Status');
but the correct way is using a single-slash (/). (the code was edited for include you suggestion)
Pingback: Tweets that mention Getting IP address geolocation info with delphi « The Road to Delphi – a Blog About Delphi Programming (mostly) -- Topsy.com
June 24, 2013 at 8:32 am
Error when calling upon the procedure??
July 8, 2013 at 12:26 pm
Can you add more details about your comment?