I want to extract a user country name from visitors\' IP addresses.
I could get the IP address with remote_ip
. But what could be
the easiest way to get
The gem geoip can be replaced with the new gem maxminddb. It support new MaxMind db format.
db = MaxMindDB.new('./GeoLite2-City.mmdb')
ret = db.lookup('74.125.225.224')
ret.found? # => true
ret.country.name # => 'United States'
ret.country.name('zh-CN') # => '美国'
ret.country.iso_code # => 'US'
ret.city.name(:fr) # => 'Mountain View'
ret.subdivisions.most_specific.name # => 'California'
ret.location.latitude # => -122.0574
Try the IP2Location Ruby
https://github.com/ip2location/ip2location-ruby
Download the free LITE database from http://lite.ip2location.com/ and use below.
gem install ip2location_ruby
require 'ip2location_ruby'
i2l = Ip2location.new.open("./data/IP-COUNTRY-SAMPLE.BIN")
record = i2l.get_all('8.8.8.8')
print 'Country Code: ' + record.country_short + "\n"
print 'Country Name: ' + record.country_long + "\n"
print 'Region Name: ' + record.region + "\n"
print 'City Name: ' + record.city + "\n"
print 'Latitude: '
print record.latitude
print "\n"
print 'Longitude: '
print record.longitude
print "\n"
print 'ISP: ' + record.isp + "\n"
print 'Domain: ' + record.domain + "\n"
print 'Net Speed: ' + record.netspeed + "\n"
print 'Area Code: ' + record.areacode + "\n"
print 'IDD Code: ' + record.iddcode + "\n"
print 'Time Zone: ' + record.timezone + "\n"
print 'ZIP Code: ' + record.zipcode + "\n"
print 'Weather Station Code: ' + record.weatherstationname + "\n"
print 'Weather Station Name: ' + record.weatherstationcode + "\n"
print 'MCC: ' + record.mcc + "\n"
print 'MNC: ' + record.mnc + "\n"
print 'Mobile Name: ' + record.mobilebrand + "\n"
print 'Elevation: '
print record.elevation
print "\n"
print 'Usage Type: ' + record.usagetype + "\n"
I'm using this one-liner:
locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
The simplest is to use an existing web service for this.
There are plugins that let you do much more, including making your models geolocation-aware (geokit-rails) automatically, but if all you need is a country code for example, simply sending an HTTP Get to http://api.hostip.info/country.php
(there are other services but this one does not require an API key) will return it, e.g. :
Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php'))
=> US
Or polling http://api.hostip.info/ will return a full XML response with city, latitude, longitude, etc.
Be aware that the results you get are not 100% accurate. For example, right now I'm in France but reported as in Germany. This will be the case for pretty much any IP-based service.
I've just published a gem for the IPLocate.io API which I created.
Super easy, no databases to download, and 1,500 free requests per day:
require 'iplocate'
# Look up an IP address
results = IPLocate.lookup("8.8.8.8")
# Or with an API key
results = IPLocate.lookup("8.8.8.8", "abcdef")
results["country"]
# "United States"
results["country_code"]
# "US"
results["org"]
# "Google LLC"
results.inspect
# {
# "ip"=>"8.8.8.8",
# "country"=>"United States",
# "country_code"=>"US",
# "city"=>nil,
# "continent"=>"North America",
# "latitude"=>37.751,
# "longitude"=>-97.822,
# "time_zone"=>nil,
# "postal_code"=>nil,
# "org"=>"Google LLC",
# "asn"=>"AS15169"
# }
It can also be used without a gem by just using Ruby's Net::HTTP
and URI
:
response = Net::HTTP.get( URI.parse( "https://www.iplocate.io/api/lookup/8.8.8.8" ) )
The request will return JSON so you can parse it and access it as follows:
country = JSON.parse( response )["country"]
# => "US"