Получение местоположения с IP-адреса

205

Я хочу получить информацию о городе, штате и стране посетителя с его IP-адреса, чтобы я мог настроить свою веб-страницу в соответствии с их местоположением. Есть ли хороший и надежный способ сделать это в PHP? Я использую JavaScript для сценариев на стороне клиента, PHP для сценариев на стороне сервера и MySQL для базы данных.

Бен Доулинг
источник
Это в значительной степени дубликат stackoverflow.com/questions/348614/… .
Чарли Мартин

Ответы:

255

Вы можете загрузить бесплатную базу данных GeoIP и найти IP-адрес локально, или вы можете использовать стороннюю службу и выполнить удаленный поиск. Это более простой вариант, так как он не требует настройки, но вносит дополнительную задержку.

Один сторонний сервис, который вы можете использовать, мой, http://ipinfo.io . Они предоставляют имя хоста, геолокацию, владельца сети и дополнительную информацию, например:

$ curl ipinfo.io/8.8.8.8
{
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com",
  "loc": "37.385999999999996,-122.0838",
  "org": "AS15169 Google Inc.",
  "city": "Mountain View",
  "region": "CA",
  "country": "US",
  "phone": 650
}

Вот пример PHP:

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
echo $details->city; // -> "Mountain View"

Вы также можете использовать его на стороне клиента. Вот простой пример jQuery:

$.get("https://ipinfo.io/json", function (response) {
    $("#ip").html("IP: " + response.ip);
    $("#address").html("Location: " + response.city + ", " + response.region);
    $("#details").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Client side IP geolocation using <a href="http://ipinfo.io">ipinfo.io</a></h3>

<hr/>
<div id="ip"></div>
<div id="address"></div>
<hr/>Full response: <pre id="details"></pre>

Бен Доулинг
источник
1
Возможно, вы захотите убедиться, что вы добавили json в конец URL-адреса, чтобы обеспечить возврат json вместо полной веб-страницы. $ details = json_decode (file_get_contents (" ipinfo.io {$ ip} / json"));
Даг
1
@Manatax Это не так, потому что тогда было бы невозможно проанализировать ответ сервера.
Ja͢ck
3
Не похоже на очень надежный сервис. Я получаю nullназвание моего города. Это не маленький город или что-то в этом роде, но он все равно не может его найти. Если это не работает в пределах США, я сомневаюсь, как часто это будет также возвращать ноль за пределами США.
Дерек 功夫 會 功夫
2
результат не точный .. регион, город почтовый
Марк Джеррил Мирандилья
2
ВНИМАНИЕ: По состоянию на январь / 2019 г. некоторые люди сообщали, что этот URL- адрес ipinfo небезопасен для вирустотала из-за трояна. Голоса были между 2015 и 2018
Рикардо
55

Мысль я бы опубликовал, так как никто, похоже, не предоставил информацию об этом конкретном API, но он возвращает именно то, что мне нужно, и вы можете получить его в нескольких форматах json, xml and csv.

 $location = file_get_contents('http://freegeoip.net/json/'.$_SERVER['REMOTE_ADDR']);
 print_r($location);

Это даст вам все, что вы, возможно, захотите:

{
      "ip": "77.99.179.98",
      "country_code": "GB",
      "country_name": "United Kingdom",
      "region_code": "H9",
      "region_name": "London, City of",
      "city": "London",
      "zipcode": "",
      "latitude": 51.5142,
      "longitude": -0.0931,
      "metro_code": "",
      "areacode": ""

}
Джейми Хатбер
источник
1
Эй, Джейми FreegeoIp.net не работает. Есть ли другой путь?
Ади
Извините, не в данный момент, но это позор, так как это сервис, который я использую на своих живых сайтах. Будем надеяться, что они когда-нибудь вернутся назад
Джейми Хатбер
2
в основном вниз и редко дает какой-либо регион или город
Рахул Аман
2
Служба Тони в Azure, кажется, работает быстро и надежно: freegeoip2
Gustav
1
К сожалению, эта служба будет отключена 1 июля 2018 года в соответствии с этим сообщением: «Эта конечная точка API устарела и перестанет работать 1 июля 2018 года. Для получения дополнительной информации посетите сайт: github.com/apilayer/freegeoip#readme \
Julio Bailon
20

Чистый пример Javascript, использующий сервисы https://geolocation-db.com. Они предоставляют решение обратного вызова JSON и JSONP.

Не требуется jQuery!

<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geolocation-db.com</title>
</head>
<body>
    <div>Country: <span id="country"></span></div>
    <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
    <div>Postal: <span id="postal"></span></div>
    <div>Latitude: <span id="latitude"></span></div>
    <div>Longitude: <span id="longitude"></span></div>
    <div>IP address: <span id="ipv4"></span></div>                             
</body>
<script>

    var country = document.getElementById('country');
    var state = document.getElementById('state');
    var city = document.getElementById('city');
    var postal = document.getElementById('postal');
    var latitude = document.getElementById('latitude');
    var longitude = document.getElementById('longitude');
    var ip = document.getElementById('ipv4');

    function callback(data)
    {
        country.innerHTML = data.country_name;
        state.innerHTML = data.state;
        city.innerHTML = data.city;
        postal.innerHTML = data.postal;
        latitude.innerHTML = data.latitude;
        longitude.innerHTML = data.longitude;
        ip.innerHTML = data.IPv4;
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://geoilocation-db.com/json/geoip.php?jsonp=callback';
    var h = document.getElementsByTagName('script')[0];
    h.parentNode.insertBefore(script, h);

</script> 
</html>
Курт Ван ден Бранден
источник
Есть ли ограничения, связанные с использованием https://geoilocation-db.comAPI?
Приянка Шарма
16

Используя Google APIS:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script>
contry_code = google.loader.ClientLocation.address.country_code
city = google.loader.ClientLocation.address.city
region = google.loader.ClientLocation.address.region
</script>
Рапозо
источник
9
The geolocation functionality in the Loader hasn't been retired, per se. We stopped documenting it several years ago and have recommended the HTML-based solutions due to their improved accuracy, but the functionality itself has not been removed from the Loader at this time. code.google.com/p/google-ajax-apis/issues/detail?id=586
TheFrost
Как насчет качества этой геолокации Google APIS IP? (это так или я не прав?), по сравнению с другими сервисами, такими как ipinfo.io ?
Basj
Я попросил ~ 30 человек в разных городах, и качество геолокации Google APIS IP низкое по сравнению с ipinfo.io
Basj
1
@Basj Google API работает как шарм, в то время как ipinfo.io показывает, что я нахожусь в США, в то время как я на самом деле в центральной Европе
patryk
15

Вам нужно использовать внешний сервис ... такой как http://www.hostip.info/ если вы выполните поиск в Google по запросу "geo-ip", вы можете получить больше результатов.

API Host-IP основан на HTTP, поэтому вы можете использовать его на PHP или JavaScript в зависимости от ваших потребностей.

ноль
источник
6
Я пользуюсь hostip.info уже год, и меня это не впечатляет. Обычно возвращаются неизвестные чеки 9/10
арон
согласился, это говорит мне, что я живу в Уокинге ... Справедливости ради, он понял, что ГБ был прав ... Но я в Лондоне.
Джейми Хатбер
2
Имейте в виду, что любая услуга будет настолько хороша, насколько доступна общедоступная информация / данные. Из соображений конфиденциальности эта информация может быть только "настолько хорошей". Если это сделает вашу страну правильной и хотя бы близкой к штату / провинции, я бы посчитал это ВЫИГРЫШОМ. Если вы используете это для поиска информации для атаки DOS, имейте в виду, что IP-адреса могут даже быть недействительными (не назначаться никому или вне допустимого диапазона общедоступных IP-адресов).
eselk
На их сайте я получаю "Местоположение: ... на самом деле мы понятия не имеем". Все, что мне нужно было знать
Боян Когой,
15

Я написал бота с помощью API из ipapi.co , вот как вы можете получить местоположение для IP-адреса (например 1.2.3.4) в php:

Установить заголовок:

$opts = array('http'=>array('method'=>"GET", 'header'=>"User-Agent: mybot.v0.7.1"));
$context = stream_context_create($opts);

Получить ответ JSON

echo file_get_contents('https://ipapi.co/1.2.3.4/json/', false, $context);

получить конкретное поле (страна, часовой пояс и т. д.)

echo file_get_contents('https://ipapi.co/1.2.3.4/country/', false, $context);
Jaimes
источник
1
@Eoin удалил это. Похоже, IP-адрес phpfiddle ограничен.
Джеймс
10

Этот вопрос защищен, что я понимаю. Тем не менее, я не вижу ответа здесь, я вижу, что многие люди показывают, что они придумали, имея один и тот же вопрос.

В настоящее время существует пять региональных интернет-реестров с различной степенью функциональности, которые служат первым контактным лицом в отношении прав собственности на ИС. Процесс постоянно меняется, поэтому различные службы здесь работают иногда, а в другое - нет.

Кто является (очевидно) древним протоколом TCP, однако - изначально он работал путем подключения к порту 43, что затрудняет его маршрутизацию через арендованные соединения, через брандмауэры ... и т. Д.

На данный момент - большинство Who Is делают через RESTful HTTP и ARIN, RIPE и APNIC имеют RESTful-сервисы, которые работают. LACNIC возвращает 503, и AfriNIC, по-видимому, не имеет такого API. (Однако у всех есть онлайн-сервисы.)

Это даст вам - адрес зарегистрированного владельца IP, но - не местоположение вашего клиента - вы должны получить его от них, а также - вы должны попросить его. Кроме того, прокси-серверы - это наименьшее беспокойство при проверке IP-адреса, который, по вашему мнению, является отправителем.

Люди не ценят идею о том, что их отслеживают, поэтому, по моим мыслям, получите это от вашего клиента напрямую и с их разрешения и ожидайте, что многие откажутся от этой идеи.

jinzai
источник
8

Посмотрите на API от hostip.info - он предоставляет много информации.
Пример в PHP:

$data = file_get_contents("http://api.hostip.info/country.php?ip=12.215.42.19");
//$data contains: "US"

$data = file_get_contents("http://api.hostip.info/?ip=12.215.42.19");
//$data contains: XML with country, lat, long, city, etc...

Если вы доверяете hostip.info, похоже, это очень полезный API.

Исаак Уоллер
источник
1
UNF. по сравнению с другими сервисами HostIP не работает. Однако,
www.ip-adress.com
8

Служба в ответе Бен Даулинга изменилась, так что теперь все стало проще. Чтобы найти местоположение, просто сделайте:

// no need to pass ip any longer; ipinfo grabs the ip of the person requesting
$details = json_decode(file_get_contents("http://ipinfo.io/"));
echo $details->city; // city

Координаты возвращаются в одной строке, например, '31, -80 ', поэтому оттуда вы просто:

$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80'
echo $coordinates[0]; // latitude
echo $coordinates[1]; // longitude
Исаак Аскью
источник
4
Вы правы, что ipinfo.io по умолчанию вернет детали для IP- адреса звонящего. Если у вас PHP-сайт, то это будет IP вашего сервера, а не IP-адрес пользователя. Вот почему вам нужно передать $ _SERVER ['REMOTE_ADDR']. Если вы просто хотите получить координаты, вам будет проще добавить / loc к URL, чтобы получить только это поле.
Бен Доулинг,
Ах, это правда! И я не знал о / loc - я немедленно исправлю это на своем сайте.
Исаак Аскью
7

Предполагая, что вы хотите сделать это самостоятельно и не полагаться на других провайдеров, IP2Nation предоставляет базу данных MySQL сопоставлений, которые обновляются по мере того, как региональные реестры меняют ситуацию.

Джеймс Кейп
источник
Я использовал внешний сервис, и вдруг мой сайт стал очень медленным. Внешней службе потребовалось добрых 20 секунд, чтобы отправить информацию - что, очевидно, пагубно для посетителей. Поэтому решил сделать это сам, и это идеальное решение. Большое спасибо.
Williamz902
7

Я запускаю сервис на IPLocate.io , который вы можете подключить бесплатно одним простым вызовом:

<?php
$res = file_get_contents('https://www.iplocate.io/api/lookup/8.8.8.8');
$res = json_decode($res);

echo $res->country; // United States
echo $res->continent; // North America
echo $res->latitude; // 37.751
echo $res->longitude; // -97.822

var_dump($res);

$resОбъект будет содержать ваши геолокации поля , как country,city и т.д.

Проверьте документы для получения дополнительной информации.

ttarik
источник
7

Мне нравится бесплатный GeoLite City от Maxmind, который работает для большинства приложений и из которого вы можете перейти на платную версию, если она недостаточно точна. Существует PHP API включен, а также для других языков. И если вы используете Lighttpd в качестве веб-сервера, вы можете даже использовать модуль для получения информации в переменной SERVER для каждого посетителя, если это то, что вам нужно.

Я должен добавить, что есть также бесплатная Geolite Country (которая будет быстрее, если вам не нужно точно указывать город, из которого исходит IP) и Geolite ASN (если вы хотите знать, кому принадлежит IP), и что в конечном итоге все это загружается на ваш собственный сервер, обновляется каждый месяц и довольно быстро выполняет поиск с помощью предоставленных API, поскольку в них указано «тысячи поисков в секунду».

lpfavreau
источник
1
Вы можете рассмотреть IP2Location LITE lite.ip2location.com, который является бесплатным. Он имеет информацию о почтовом индексе, что очень полезно.
Майкл С.
6

У PHP есть расширение для этого.

С PHP.net:

Расширение GeoIP позволяет вам найти местоположение IP-адреса. Город, штат, страна, долгота, широта и другая информация, такая как, например, ISP и тип соединения, может быть получена с помощью GeoIP.

Например:

$record = geoip_record_by_name($ip);
echo $record['city'];
Ян Хантер
источник
3
Это всего лишь модуль php для базы данных MaxMind, которая является платным. (Бесплатные «облегченные» версии очень неточны.) Не говоря уже о том, что это плохо, но на самом деле это полезно только в коммерческих целях.
Кто-то
6

Ipdata.co - это быстрый высокодоступный API-интерфейс для определения географического местоположения с надежной производительностью.

Это чрезвычайно масштабируемая система с 10 конечными точками по всему миру, каждая из которых способна обрабатывать> 10 000 запросов в секунду!

В этом ответе используется «тестовый» API-ключ, который очень ограничен и предназначен только для тестирования нескольких вызовов. Зарегистрируйтесь для получения своего бесплатного ключа API и ежедневно получайте до 1500 запросов на разработку.

В php

php > $ip = '8.8.8.8';
php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
php > echo $details->region;
California
php > echo $details->city;
Mountain View
php > echo $details->country_name;
United States
php > echo $details->latitude;
37.751

Вот пример на стороне клиента, показывающий, как вы получите страну, регион и город;

$.get("https://api.ipdata.co?api-key=test", function (response) {
	$("#response").html(JSON.stringify(response, null, 4));
  $("#country").html('Country: ' + response.country_name);
  $("#region").html('Region ' + response.region);
  $("#city").html('City' + response.city);  
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="country"></div>
<div id="region"></div>
<div id="city"></div>
<pre id="response"></pre>

Отказ от ответственности;

Я построил сервис.

Для примеров на нескольких языках см. Документы

Также посмотрите этот подробный анализ лучших API геолокации IP.

Джонатан
источник
5

В случае, если кто-то наткнется на эту тему, вот другое решение. На timezoneapi.io вы можете запросить IP-адрес и получить взамен несколько объектов (я создал сервис). Он был создан потому, что мне нужно было узнать, в каком часовом поясе находятся мои пользователи, где в мире и в какое время он сейчас.

В PHP - возвращает местоположение, часовой пояс и дату / время:

// Get IP address
$ip_address = getenv('HTTP_CLIENT_IP') ?: getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_X_FORWARDED') ?: getenv('HTTP_FORWARDED_FOR') ?: getenv('HTTP_FORWARDED') ?: getenv('REMOTE_ADDR');

// Get JSON object
$jsondata = file_get_contents("http://timezoneapi.io/api/ip/?" . $ip_address);

// Decode
$data = json_decode($jsondata, true);

// Request OK?
if($data['meta']['code'] == '200'){

    // Example: Get the city parameter
    echo "City: " . $data['data']['city'] . "<br>";

    // Example: Get the users time
    echo "Time: " . $data['data']['datetime']['date_time_txt'] . "<br>";

}

Используя jQuery:

// Get JSON object
$.getJSON('https://timezoneapi.io/api/ip', function(data){

    // Request OK?
    if(data.meta.code == '200'){

        // Log
        console.log(data);

        // Example: Get the city parameter
        var city = data.data.city;
        alert(city);

        // Example: Get the users time
        var time = data.data.datetime.date_time_txt;
        alert(time);

    }

});
Майкл Нильссон
источник
4

Ниже приведена измененная версия фрагмента, который я обнаружил и использует http://ipinfodb.com/ip_locator.php. для получения информации. Имейте в виду, что вы также можете подать заявку на ключ API и использовать API напрямую, чтобы получить предоставленную информацию по своему усмотрению.

отрывок

function detect_location($ip=NULL, $asArray=FALSE) {
    if (empty($ip)) {
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }
        elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }
        else { $ip = $_SERVER['REMOTE_ADDR']; }
    }
    elseif (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost') {
        $ip = '8.8.8.8';
    }

    $url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip);
    $i = 0; $content; $curl_info;

    while (empty($content) && $i < 5) {
        $ch = curl_init();
        $curl_opt = array(
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER  => 1,
            CURLOPT_URL => $url,
            CURLOPT_TIMEOUT => 1,
            CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_HOST'],
        );
        if (isset($_SERVER['HTTP_USER_AGENT'])) $curl_opt[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
        curl_setopt_array($ch, $curl_opt);
        $content = curl_exec($ch);
        if (!is_null($curl_info)) $curl_info = curl_getinfo($ch);
        curl_close($ch);
    }

    $araResp = array();
    if (preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs)) $araResp['city'] = trim($regs[1]);
    if (preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs)) $araResp['state'] = trim($regs[1]);
    if (preg_match('{<li>Country : ([^<]*)}i', $content, $regs)) $araResp['country'] = trim($regs[1]);
    if (preg_match('{<li>Zip or postal code : ([^<]*)</li>}i', $content, $regs)) $araResp['zip'] = trim($regs[1]);
    if (preg_match('{<li>Latitude : ([^<]*)</li>}i', $content, $regs)) $araResp['latitude'] = trim($regs[1]);
    if (preg_match('{<li>Longitude : ([^<]*)</li>}i', $content, $regs)) $araResp['longitude'] = trim($regs[1]);
    if (preg_match('{<li>Timezone : ([^<]*)</li>}i', $content, $regs)) $araResp['timezone'] = trim($regs[1]);
    if (preg_match('{<li>Hostname : ([^<]*)</li>}i', $content, $regs)) $araResp['hostname'] = trim($regs[1]);

    $strResp = ($araResp['city'] != '' && $araResp['state'] != '') ? ($araResp['city'] . ', ' . $araResp['state']) : 'UNKNOWN';

    return $asArray ? $araResp : $strResp;
}

Использовать

detect_location();
//  returns "CITY, STATE" based on user IP

detect_location('xxx.xxx.xxx.xxx');
//  returns "CITY, STATE" based on IP you provide

detect_location(NULL, TRUE);    //   based on user IP
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.host.name.net" }

detect_location('xxx.xxx.xxx.xxx', TRUE);   //   based on IP you provide
//  returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.host.name.net" }
SpYk3HH
источник
4

Если вам нужно узнать местоположение с IP-адреса, вы можете использовать надежный гео-IP-сервис, вы можете получить более подробную информацию здесь . Он поддерживает IPv6.

В качестве бонуса он позволяет проверить, является ли ip адрес узлом tor, публичным прокси или спамером.

Вы можете использовать JavaScript или PHP, как показано ниже.

Код Javascript:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

Код php:

$result = json_decode(file_get_contents('http://ip-api.io/json/64.30.228.118'));
var_dump($result);

Вывод:

{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
Виндхьячал Кумар
источник
3

Я создал обертку для ipinfo.io . Вы можете установить его с помощью композитора.

Вы можете использовать это следующим образом:

$ipInfo = new DavidePastore\Ipinfo\Ipinfo();

//Get all the properties
$host = $ipInfo->getFullIpDetails("8.8.8.8");

//Read all the properties
$city = $host->getCity();
$country = $host->getCountry();
$hostname = $host->getHostname();
$ip = $host->getIp();
$loc = $host->getLoc();
$org = $host->getOrg();
$phone = $host->getPhone();
$region = $host->getRegion();
Давиде Пасторе
источник
2

Вы также можете воспользоваться услугой «smart-ip»:

$.getJSON("http://smart-ip.net/geoip-json?callback=?",
    function (data) {
        alert(data.countryName);
        alert(data.city);
    }
);
Роман Пушкин
источник
2

Я провел несколько тестов со службами IP-адресов, и вот несколько способов сделать это самому. Во-первых, куча ссылок на полезные веб-сайты, которые я использую:

https://db-ip.com/db Имеет бесплатный сервис ip-lookup и имеет несколько бесплатных csv-файлов, которые вы можете скачать. При этом используется бесплатный ключ API, прикрепленный к вашей электронной почте. Он ограничивает 2000 запросов в день.

http://ipinfo.io/ Бесплатный сервис ip-lookup без PHP-функций API-ключа:

//uses http://ipinfo.io/.
function ip_visitor_country($ip){
    $ip_data_in = get_web_page("http://ipinfo.io/".$ip."/json"); //add the ip to the url and retrieve the json data
    $ip_data = json_decode($ip_data_in['content'],true); //json_decode it for php use

    //this ip-lookup service returns 404 if the ip is invalid/not found so return false if this is the case.
    if(empty($ip_data) || $ip_data_in['httpcode'] == 404){
        return false;
    }else{
        return $ip_data; 
    }
}

function get_web_page($url){
    $user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';

    $options = array(
        CURLOPT_CUSTOMREQUEST  =>"GET",        //set request type post or get
        CURLOPT_POST           =>false,        //set to GET
        CURLOPT_USERAGENT      => $user_agent, //set user agent
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
    );
    $ch = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
    curl_close( $ch );  
    $header['errno']   = $err; //curl error code
    $header['errmsg']  = $errmsg; //curl error message
    $header['content'] = $content; //the webpage result (In this case the ip data in json array form)
    $header['httpcode'] = $httpCode; //the webpage response code
    return $header; //return the collected data and response codes
}

В итоге вы получите что-то вроде этого:

Array
(
    [ip] => 1.1.1.1
    [hostname] => No Hostname
    [city] => 
    [country] => AU
    [loc] => -27.0000,133.0000
    [org] => AS15169 Google Inc.
)

http://www.geoplugin.com/ Немного старше, но этот сервис дает вам кучу дополнительной полезной информации, такой как валюта страны, код континента, долгота и многое другое.


http://lite.ip2location.com/database-ip-country-region-city-latitude-longitude Предлагает несколько загружаемых файлов с инструкциями по их импорту в вашу базу данных. Если у вас есть один из этих файлов в вашей базе данных, вы можете выбрать данные довольно легко.

SELECT * FROM `ip2location_db5` WHERE IP > ip_from AND IP < ip_to

Используйте функцию php ip2long (); превратить IP-адрес в числовое значение. Например, 1.1.1.1 становится 16843009. Это позволяет сканировать диапазоны IP-адресов, предоставленные вам файлом базы данных.

Таким образом, чтобы выяснить, где 1.1.1.1 принадлежит всему, что мы делаем, запустим этот запрос:

SELECT * FROM `ip2location_db5` WHERE 16843009 > ip_from AND 16843009 < ip_to;

Это возвращает эти данные в качестве примера.

FROM: 16843008
TO: 16843263
Country code: AU
Country: Australia
Region: Queensland
City: Brisbane
Latitude: -27.46794
Longitude: 153.02809
Crecket
источник
2

Существует два широких подхода к выполнению геолокации IP: один - загрузить набор данных, разместить его в своей инфраструктуре и поддерживать его в актуальном состоянии. Это требует времени и усилий, особенно если вам необходимо поддерживать большое количество запросов. Другое решение состоит в том, чтобы использовать существующий сервис API, который управляет всей работой за вас и многое другое.

Существует много сервисов API Geolocation: Maxmind, Ip2location, Ipstack, IpInfo и т. Д. Недавно компания, в которой я работаю, перешла на Ipregistry ( https://ipregistry.co ), и я участвовал в процессе принятия решений и реализации. Вот некоторые элементы, которые вы должны учитывать при поиске API геолокации IP:

  • Точный ли сервис? они используют один источник информации?
  • Могут ли они действительно справиться с вашей нагрузкой?
  • Обеспечивают ли они постоянное и быстрое время отклика во всем мире (кроме случаев, когда ваши пользователи относятся к конкретной стране)?
  • Какова их модель ценообразования?

Вот пример, чтобы получить информацию о геолокации IP (но также информацию об угрозе и пользовательском агенте, используя один вызов):

$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("https://api.ipregistry.co/{$ip}?key=tryout"));
echo $details->location;

Примечание: я здесь не для того, чтобы рекламировать Ipregistry и сказать, что это лучшее, но я потратил много времени на анализ существующих решений, и их решение действительно многообещающе.

BonieE
источник
-1

Если вы ищете обновленную / точную базу данных, я рекомендую использовать ее здесь, потому что она показывала мое точное местоположение, которое не было включено во многие другие службы, когда я тестировал.
(Мой город был, Rashtи моя страна была Iranс этим IP-адресом: 2.187.21.235когда я тестировал.)

Я рекомендую использовать базу данных, а не методы API, потому что она будет обрабатываться намного быстрее локально.

Мойтаба Резаян
источник
-1

Хорошо, ребята, спасибо за ваши предложения; Несмотря на то, что у меня есть 6k + IP-адресов, некоторые службы не смогли выполнить мои запросы из-за некоторых ограничений; Таким образом, вы можете использовать их все в резервном режиме;

Если у нас есть исходный файл в следующем формате:

user_id_1  ip_1
user_id_2  ip_2
user_id_3  ip_1

чем вы могли бы использовать эту простую команду примера (PoC) для Yii:

class GeoIPCommand extends CConsoleCommand
{

public function actionIndex($filename = null)
{
    //http://freegeoip.net/json/{$ip} //10k requests per hour
    //http://ipinfo.io/{$ip}/json //1k per day
    //http://ip-api.com/json/{$ip}?fields=country,city,regionName,status //150 per minute

    echo "start".PHP_EOL;

    $handle      = fopen($filename, "r");
    $destination = './good_locations.txt';
    $bad         = './failed_locations.txt';
    $badIP       = [];
    $goodIP      = [];

    $destHandle = fopen($destination, 'a+');
    $badHandle  = fopen($bad, 'a+');

    if ($handle)
    {
        while (($line = fgets($handle)) !== false)
        {
            $result = preg_match('#(\d+)\s+(\d+\.\d+\.\d+\.\d+)#', $line, $id_ip);
            if(!$result) continue;

            $id = $id_ip[1];
            $ip = $id_ip[2];
            $ok = false;

            if(isset($badIP[$ip])) 
            {
                fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
                continue;
            }

            if(isset($goodIP[$ip]))
            {
                fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]);
                continue;
            }

            $query = @json_decode(file_get_contents('http://freegeoip.net/json/'.$ip));
            $city = property_exists($query, 'region_name')? $query->region_name : '';
            $city .= property_exists($query, 'city') && $query->city && ($query->city != $city) ? ', ' . $query->city : '';

            if($city)
            {
                fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
                $ok = true;
            }

            if(!$ok)
            {
                $query = @json_decode(file_get_contents('http://ip-api.com/json/'. $ip.'?fields=country,city,regionName,status'));
                if($query && $query->status == 'success')
                {
                    $city = property_exists($query, 'regionName')? $query->regionName : '';
                    $city .= property_exists($query, 'city') && $query->city ? ',' . $query->city : '';

                    if($city)
                    {
                        fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
                        echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
                        $ok = true;
                    }
                }
            }

            if(!$ok)
            {
                $badIP[$ip] = false;
                fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
                echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, 'Unknown');
            }

            if($ok)
            {
                $goodIP[$ip] = $city;
            }
        }

        fclose($handle);
        fclose($badHandle);
        fclose($destHandle);
    }else{
        echo 'Can\'t open file' . PHP_EOL; 
        return;
    }

    return;
}

}

Это какой-то дерьмовый код, но он работает. использование:

./yiic geoip index --filename="./source_id_ip_list.txt"

Не стесняйтесь использовать, модифицировать и делать это лучше)

alexglue
источник