Получение имени страны-пользователя от исходного IP-адреса с помощью Ruby on Rails
Я хочу извлечь имя страны пользователя из IP-адресов посетителей.
Я могу получить IP-адрес с remote_ip
. Но что может быть
самый простой способ получить название страны?
Это не должно быть сверхточным. Любая рубиновая библиотека (драгоценный камень или плагин) для этого?
Я хочу простое и простое решение для этого.
Ответы
Ответ 1
Вы можете использовать geoip
gem.
environment.rb
config.gem 'geoip'
Загрузите GeoIP.dat.gz
из http://www.maxmind.com/app/geolitecountry
. разархивируйте файл. Ниже указано значение #{RAILS_ROOT}/db
dir.
@geoip ||= GeoIP.new("#{RAILS_ROOT}/db/GeoIP.dat")
remote_ip = request.remote_ip
if remote_ip != "127.0.0.1" #todo: check for other local addresses or set default value
location_location = @geoip.country(remote_ip)
if location_location != nil
@model.country = location_location[2]
end
end
Ответ 2
Вы также можете использовать Geocoder"
Это просто облегчит вам жизнь. Поместите следующую строку в свой Gemfile и выполните команду установки пакета
gem 'geocoder'
Используя этот драгоценный камень, вы можете легко получить страну, ip или даже город исходящего IP. Пример ниже
request.ip # => "182.185.141.75"
request.location.city # => ""
request.location.country # => "Pakistan"
Ответ 3
Я использую этот однострочный слой:
locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
Ответ 4
Простейшим является использование существующей веб-службы для этого.
Есть плагины, которые позволяют вам делать гораздо больше, в том числе сделать ваши модели геолокации (geokit-rails) автоматически, но если вам нужно всего лишь код страны, просто отправляя HTTP Get to http://api.hostip.info/country.php
(там другие сервисы, но для этого не требуется ключ API) вернет его, например
Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php'))
=> US
Или опрос http://api.hostip.info/ вернет полный XML-ответ с городом, широтой, долготой и т.д.
Помните, что полученные результаты не на 100% точны. Например, сейчас я во Франции, но, как и в Германии. Это будет иметь место практически для любого IP-сервиса.
Ответ 5
Одна из услуг, которую вы могли бы использовать для этого, - моя, https://ipinfo.io. Он дает вам код страны и множество других деталей:
$ curl ipinfo.io
{
"ip": "24.6.61.239",
"hostname": "c-24-6-61-239.hsd1.ca.comcast.net",
"city": "Mountain View",
"region": "California",
"country": "US",
"loc": "37.3845,-122.0881",
"org": "AS7922 Comcast Cable Communications, LLC",
"postal": "94040"
}
Если вам просто нужна страна, вы можете получить это, запросив /country
$ curl ipinfo.io/country
US
Затем вы можете сопоставить код страны с именем, используя данные http://country.io, или используя пример в http://ipinfo.io/developers/full-country-names
Ответ 6
Я только что опубликовал гем для API IPLocate.io, который я создал.
Супер просто, нет баз данных для загрузки и 1500 бесплатных запросов в день:
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"
# }
Без драгоценных камней
Его также можно использовать без драгоценного камня, просто используя Ruby Net::HTTP
и URI
:
response = Net::HTTP.get( URI.parse( "https://www.iplocate.io/api/lookup/8.8.8.8" ) )
Запрос вернет JSON, чтобы вы могли проанализировать его и получить к нему доступ следующим образом:
country = JSON.parse( response )["country"]
# => "US"
Ответ 7
Вы можете попробовать "Ядро поиска Яндекса" , служба возвращает долготу, широту и точность.
conn = YandexLocator::Client.new
result = conn.lookup(ip: "109.252.52.39")
# => {"position"=>{"altitude"=>0.0, "altitude_precision"=>30.0, "latitude"=>55.75395965576172, "longitude"=>37.62039184570312, "precision"=>100000.0, "type"=>"ip"}}
Ответ 8
Вот пример Ruby, вызывающий API ipdata.co.
Это быстро и надежно работает благодаря наличию 10 глобальных конечных точек, каждая из которых способна обрабатывать> 10 000 запросов в секунду!
В этом ответе используется "тестовый" API-ключ, который очень ограничен и предназначен только для тестирования нескольких вызовов. Зарегистрируйтесь для получения своего бесплатного ключа API и получите до 1500 запросов в день на разработку.
Замените 78.8.53.5
на любой ip, который хотите посмотреть
require 'rubygems' if RUBY_VERSION < '1.9'
require 'rest_client'
headers = {
:accept => 'application/json'
}
response = RestClient.get 'https://api.ipdata.co/78.8.53.5?api-key=test', headers
puts response
Это дало бы вам
{
"ip": "78.8.53.5",
"is_eu": true,
"city": "G\u0142og\u00f3w",
"region": "Lower Silesia",
"region_code": "DS",
"country_name": "Poland",
"country_code": "PL",
"continent_name": "Europe",
"continent_code": "EU",
"latitude": 51.6557,
"longitude": 16.089,
"asn": "AS12741",
"organisation": "Netia SA",
"postal": "67-200",
"calling_code": "48",
"flag": "https://ipdata.co/flags/pl.png",
"emoji_flag": "\ud83c\uddf5\ud83c\uddf1",
"emoji_unicode": "U+1F1F5 U+1F1F1",
"carrier": {
"name": "Netia",
"mcc": "260",
"mnc": "07"
},
"languages": [
{
"name": "Polish",
"native": "Polski"
}
],
"currency": {
"name": "Polish Zloty",
"code": "PLN",
"symbol": "z\u0142",
"native": "z\u0142",
"plural": "Polish zlotys"
},
"time_zone": {
"name": "Europe/Warsaw",
"abbr": "CEST",
"offset": "+0200",
"is_dst": true,
"current_time": "2018-08-29T15:34:23.518065+02:00"
},
"threat": {
"is_tor": false,
"is_proxy": false,
"is_anonymous": false,
"is_known_attacker": false,
"is_known_abuser": false,
"is_threat": false,
"is_bogon": false
},
}
Ответ 9
Попробуйте IP2Location Ruby
https://github.com/ip2location/ip2location-ruby
Предпосылка
Загрузите бесплатную базу данных LITE из http://lite.ip2location.com/ и используйте ниже.
Установка
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"
Ответ 10
geoip
gem больше не работает с новыми базами данных MaxMind. Существует новый гем, который делает это, MaxMind-DB-Reader-ruby.
Просто скачайте двоичные файлы City или Country, gzip-базы данных из MaxMind, разархивируйте и используйте следующий вид кода:
require 'maxmind/db'
reader = MaxMind::DB.new('GeoIP2-City.mmdb', mode: MaxMind::DB::MODE_MEMORY)
# you probably want to replace 1.1.1.1 with request.remote_ip
# or request.env['HTTP_X_FORWARDED_FOR']
ip_addr = '1.1.1.1'
record = reader.get(ip_addr)
if record.nil?
puts '#{ip_addr} was not found in the database'
else
puts record['country']['iso_code']
puts record['country']['names']['en']
end
reader.close
Адаптируйте в зависимости от ваших потребностей. Я создал метод в инициализаторе, который я могу вызывать по мере необходимости.