Release 1.1

XML-сервис

Добавлено: Пятница, 13 Марта, 2009 16:07       Размещено в: Новости проекта

Убедительная просьба, если Вам надо прокачать большое количество адресов, просьба заключать их в один запрос (не более 4000 Ip в одном запросе). В скором времени будет выложен пример скрипта на perl для прокачки лога Apache.
Теперь мы подключили XML-сервис обработки запросов на определение местонахождения российских IP-адресов. Сервис обслуживается специальным сервером. Сервер получает запрос в формате XML через POST HTTP запрос, отдает ответ также в формате XML.

Сервер расположен по адресу 194.85.91.253, порт 8090, работает по протоколу HTTP. Метод GET сервером не поддерживается. Минимальный заголовок HTTP запроса выглядит следующим образом:

POST /geo/geo.html HTTP/1.1
Content-length: CL
,где CL - длина тела запроса

Формат тела запроса выглядит следующим образом:
<ipquery [id="123456"]>
<fields>
[<all/>]
[<inetnum/>]
[<inet-descr/>]
[<inet-status/>]
[<city/>]
[<region/>]
[<district/>]
[<lat/>]
[<lng/>]
</fields>
<ip-list>
<ip>62.5.128.0</ip>
<ip>144.206.192.23</ip>
….
<ip>85.44.33.22</ip>
</ip-list>
</ipquery>
,где id=”123456″ - необязательный параметр. Это идентификатор запроса, в кавычках - любые числа и буквы, ответ сервера будет содержать указанный вами id; тег <fields> содержит поля, которые вы хотите получить:
<inetnum/> - блок адресов, к которому относится искомый ip-адрес
<inet-descr/> - описание блока по базе RIPE (www.ripe.net)
<inet-status/> - статус блока по базе RIPE
<city/> - город, к которому относится искомый ip
<region/> - регион, к которому относится искомый ip
<district/> - федеральный округ РФ, к которому относится искомый ip
<lat/> - географическая широта города
<lng/> - географическая долгота города
<all/> - все вышеперечисленные поля
В теге <ip-list> содержится список ip, которые надо прокачать. Это может быть один ip, или несколько. Максимальное количество 4000 ip в одном запросе. Каждый ip обрамляется тегами <ip> и </ip>.
Формат ответа сервера:
<ip-answer id=”123456″>
<ip value=”62.5.128.0″>
<inetnum>62.5.128.0 - 62.5.128.15</inetnum>
<inet-descr>Subnetwork for VA159-RIPE</inet-descr>
<inet-status>ASSIGNED PA</inet-status>
<city>Москва</city>
<region>Москва</region>
<district>Центральный</district>
<lat>55.755787</lat>
<lng>37.617634</lng>
</ip>
….
</ip-answer>
По каждому адресу, мы получаем список полей, которые мы указали в <fields> в запросе. В вышеуказанном примере ответа в запросе был указан <all/>.
Для обращения к серверу с вашего сайта, можно использовать стандартную библиотеку HTTP (имеется практически во всех языках программирования). Подключаемся к 194.85.91.253:8090, отправляем POST запрос на /geo/geo.html, в котором содержится <ipquery>…</ipquery>. В скором времени будут выложены примеры на различных языках.

Для обращения к серверу через форму нужно вставить такой HTML код:

<form name = “index” action = “http://194.85.91.253:8090/geo/geo.html” method = “post”>
<textarea name=”address”></textarea>
<input type=”submit” value=”OK”>
</form>

Названия формы и поля <textarea> не важны. В поле textarea вставляется запрос в формате XML, указанный выше. Например:

150 комментариев на тему “XML-сервис”:

Страницы: [1] 2 3 4 5 » Показать все комментарии

  1. 1
    sunswordrie ответил:

    Чет очень намудрили с запросом, нужно просто допустим через curl сделать запрос) и как это организовать в такой структуре?

  2. 2
    Администратор ответил:
    Чет очень намудрили с запросом, нужно просто допустим через curl сделать запрос) и как это организовать в такой структуре?

    Сервер расчитан на прокачку большого количества Ip-адресов, поэтому нецелесообразно передавать в URL по одному адресу. Если нужно смотреть по одному адресу, все равно придется отправлять POST-запрос. GET (передача ip в URL) не поддерживается.

  3. 3
    sunswordrie ответил:

    Насколько понимаю, код должен быть таким?

    $data = array(
    ‘address’ => ‘144.206.192.4′
    );

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, “http://194.85.91.253:8090/geo/geo.html”);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $xml = curl_exec($ch);
    curl_close($ch);

    echo $xml;

  4. 4
    sunswordrie ответил:

    п.с. вырезало все теги xml запроса, которые указаны в примере в textarea

  5. 5
    Администратор ответил:
    п.с. вырезало все теги xml запроса, которые указаны в примере в textarea

    Как это “вырезало”?

    Насколько понимаю, код должен быть таким?

    $data = array(
    ‘address’ => ‘144.206.192.4′
    );

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, “http://194.85.91.253:8090/geo/geo.html”);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $xml = curl_exec($ch);
    curl_close($ch);

    echo $xml;

    Вы не указали теги запроса. Должно быть что-то типа:
    < ?php
    $data = "<ipquery><fields><all/></fields><ip-list><ip>144.206.192.4</ip></ip-list></ipquery>”;

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, “http://194.85.91.253:8090/geo/geo.html”);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $xml = curl_exec($ch);
    curl_close($ch);

    echo $xml;
    ?>

  6. 6
    sunswordrie ответил:

    Угу, спасибо.

  7. 7
    sunswordrie ответил:

    А можно эти данные возвращало тоже в xml формате, чтобы заюзать SimpleXMLElement на выходящую информацию и вообще всё было красиво?

  8. 8
    sunswordrie ответил:

    Код, который получился на данный момент, без xml:

    function getip($GetRIP)
    {
    $data = “”.$GetRIP.”";

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, “http://194.85.91.253:8090/geo/geo.html”);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $xml = curl_exec($ch);
    curl_close($ch);

    //echo $xml;

    $district=”!(.*?)!si”;
    $region=”!(.*?)!si”;
    $town=”!(.*?)!si”;

    preg_match($district, $xml, $main_ar["district"]);
    preg_match($region, $xml, $main_ar["region"]);
    preg_match($town, $xml, $main_ar["city"]);

    return array(”DISTRICT”=>$main_ar["district"][1], “REGION”=>$main_ar["region"][1],”TOWN”=>$main_ar["city"][1]);

    }
    echo “”; print_r(getip($_SERVER["REMOTE_ADDR"])); echo “”;

  9. 9
    sunswordrie ответил:

    Жалко не запостить, вырезает теги удалите пожалуйста это и верхнее сообщение.

  10. 10
    redline ответил:

    “А какие ограничения на количество запросов с одного IP и в каком временном интервале?” (c) Максим Месилов

  11. 11
    Администратор ответил:
    “А какие ограничения на количество запросов с одного IP и в каком временном интервале?” (c) Максим Месилов

    Пока никаких ограничений, пользуйтесь на здоровье сколько угодно :)

  12. 12
    Администратор ответил:
    Жалко не запостить, вырезает теги удалите пожалуйста это и верхнее сообщение.

    Не ясна проблема, опишите поподробнее что и где вырезает

  13. 13
    Администратор ответил:
    А можно эти данные возвращало тоже в xml формате, чтобы заюзать SimpleXMLElement на выходящую информацию и вообще всё было красиво?

    Я вас немного недопонимаю. Все данные забираются и отдаются в XML формате

  14. 14
    Администратор ответил:
    Код, который получился на данный момент, без xml:

    function getip($GetRIP)
    {
    $data = “”.$GetRIP.””;

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, “http://194.85.91.253:8090/geo/geo.html”);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $xml = curl_exec($ch);
    curl_close($ch);

    //echo $xml;

    $district=”!(.*?)!si”;
    $region=”!(.*?)!si”;
    $town=”!(.*?)!si”;

    preg_match($district, $xml, $main_ar["district"]);
    preg_match($region, $xml, $main_ar["region"]);
    preg_match($town, $xml, $main_ar["city"]);

    return array(”DISTRICT”=>$main_ar["district"][1], “REGION”=>$main_ar["region"][1],”TOWN”=>$main_ar["city"][1]);

    }
    echo “”; print_r(getip($_SERVER["REMOTE_ADDR"])); echo “”;

    Зачем все так усложнять. Ответ сервера специально сделан в XML, чтобы было легко парсить ответ. Вот пример на PERL для прокачки IP:

    #!/usr/bin/perl

    use LWP::UserAgent;

    my $ua = LWP::UserAgent->new;
    my $xml_query = “<ipquery><fields><all/></fields><ip-list><ip>144.206.192.4</ip><ip>81.176.209.240</ip></ip-list></ipquery>”;
    my $response = $ua->post(’http://194.85.91.253:8090/geo/geo.html’,Content => $xml_query);

    if ($response->is_success) {
    print $response->content; #Эта строка контента, из нее можно парсить необходимую информацию.
    }
    else {
    die $response->status_line;
    }

  15. 15
    Leonid ответил:

    спасибо за сервис!
    Вот только что-то ваша собственная форма не работает - выдаёт incorrect request :)

  16. 16
    Администратор ответил:
    спасибо за сервис!
    Вот только что-то ваша собственная форма не работает - выдаёт incorrect request :)

    Сервис находится в стадии тестирования, поэтому баги возможны. Какой именно запрос у Вас не работает? Напишите его пожалуйста в коментарии

  17. 17
    Андрей ответил:

    Какой код на PHP нужно поставить, что-то не работаю выше описаные

  18. 18
    Администратор ответил:
    Какой код на PHP нужно поставить, что-то не работаю выше описаные

    Граждане программисты на PHP!!! Выкладывайте свои рабочие варианты скриптов-клиентов нашего сервера

  19. 19
    Laney ответил:

    Задача - определение города посетителя сайта. 1 запрос - 1 IP.
    По хорошему, массив результирующий сделать двумерным, первый ключ - ip (именно тот, что передается в функцию в качестве параметра), второй - параметр из инфы об IP (аля город, страна, etc).

    <?php
    function get_ip_info($ip)
    {
    $xml_encoding = ‘windows-1251′;
    $in_charset = ‘UTF-8′;
    $out_charset = ‘windows-1251′;

    $GeoIP = array();

    $xml_query = ” . $ip . ”;
    $xml_response = ”;

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, ‘http://194.85.91.253:8090/geo/geo.html’);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_query);

    $xml_response .= curl_exec($ch);
    curl_close($ch);

    $xml = new SimpleXMLElement($xml_response);

    $GeoIP = array(
    ‘inetnum’ => ln_str_encode($xml->ip->inetnum, $in_charset, $out_charset),
    ‘inet-descr’ => ln_str_encode($xml->ip->inet-descr, $in_charset, $out_charset),
    ‘inet-status’ => ln_str_encode($xml->ip->inet-status, $in_charset, $out_charset),
    ‘city’ => ln_str_encode($xml->ip->city, $in_charset, $out_charset),
    ‘region’ => ln_str_encode($xml->ip->region, $in_charset, $out_charset),
    ‘district’ => ln_str_encode($xml->ip->district, $in_charset, $out_charset),
    ‘lat’ => ln_str_encode($xml->ip->lat, $in_charset, $out_charset),
    ‘lng’ => ln_str_encode($xml->ip->lng, $in_charset, $out_charset),
    );

    return $GeoIP;

    }

    /**
    * Convert string to requested character encoding.
    * This function performs a character set conversion on the string str from in_charset to out_charset.
    *
    * @param string $str
    * @param string $in_charset
    * @param string $out_charset
    * @return string|false results of {@link _read_cache_file()}
    */
    function ln_str_encode($str, $in_charset, $out_charset)
    {

    if (function_exists(’mb_convert_encoding’))
    {
    return mb_convert_encoding($str, $out_charset, $in_charset);
    }
    else
    {
    return iconv($in_charset, $out_charset, $str);
    }

    }

    $ip_info = get_ip_info($_SERVER['REMOTE_ADDR']);

    /*
    foreach ($ip_info as $key => $val)
    {
    echo $key . ‘: ‘ . $val . ”;
    }
    */

    echo ‘Город: ‘ . $ip_info['city'] . ”;
    echo ‘Регион: ‘ . $ip_info['region'] . ”;
    echo ‘Округ: ‘ . $ip_info['district'] . ”;

    ?>

  20. 20
    Leonid ответил:

    >>> Какой именно запрос у Вас не работает? Напишите его пожалуйста в коментарии

    Всё очень просто :) Решил попробовать Вашу же форму (она приведена в конце поста). ИП указал одного из гугловских серверов. Жму ‘Ок’ - ошибка

  21. 21
    Администратор ответил:
    >>> Какой именно запрос у Вас не работает? Напишите его пожалуйста в коментарии

    Всё очень просто :) Решил попробовать Вашу же форму (она приведена в конце поста). ИП указал одного из гугловских серверов. Жму ‘Ок’ - ошибка

    Все работает. Возможно вы забыли обрамить запрос каким-либо из обязательных XML тегов. Помимо искомых ip (их надо обрамлять тегами <ip> и </ip>, например <ip>1.2.3.4</ip>) в форму надо вбить теги <ip-list>, <fields>, <ipquery>. Формат подробно описан в посте! Если в форму ввести только ip без XML тегов, сервер выдаст ошибку “incorrect request”.

  22. 22
    Leo ответил:

    Может быть, как необязательное поле/атрибут добавить кодировку?

  23. 23
    Администратор ответил:
    Может быть, как необязательное поле/атрибут добавить кодировку?

    Хорошее предложение, возможно в скором мы реализуем данную функцию. Пока сервер отдает ответ только в windows-1251

  24. 24
    Jozzyk ответил:

    Ктонибудь проверял код Laney ? Я плохо в php шарю и у меня ничего не выходит :-(

  25. 25
    redline ответил:

    Как вариант, но советую почитать комменты и добавить необходимое, в часности кеширование по IP и установки CURLOPT_CONNECTTIMEOUT.

    п.с. Данный сервис просто отличный, тем кто не юзает хеш бан надо замутить, чтобы с одним и тем же запросом в день по 20 раз не обращались. Он всё равно не изменится, а точнее вероятность этого крайне мала.

    Сам вариант кода: http://sunswordred.habrahabr.ru/blog/54728/.

  26. 26
    Сергей ответил:

    RE: Ктонибудь проверял код Laney ? Я плохо в php шарю и у меня ничего не выходит :-(

    Проверил, работает.
    Значения переменных
    $xml_query и $xml_response укажите.

  27. 27
    Администратор ответил:
    Как вариант, но советую почитать комменты и добавить необходимое, в часности кеширование по IP и установки CURLOPT_CONNECTTIMEOUT.

    п.с. Данный сервис просто отличный, тем кто не юзает хеш бан надо замутить, чтобы с одним и тем же запросом в день по 20 раз не обращались. Он всё равно не изменится, а точнее вероятность этого крайне мала.

    Сам вариант кода: http://sunswordred.habrahabr.ru/blog/54728/.

    Если бы по 20 раз… по 20000 раз обращаются :) сейчас вроде бы поубавили пыл.
    Спасибо Вам за отзыв, будем работать над улучшением сервиса!

  28. 28
    Jozzyk ответил:

    вопщем я так и не разобрался как их xml ответа вычленить нужную информацию… сделал по топорному. (мне нужны были только город и регион)

    <?php
    $ip=$_SERVER['REMOTE_ADDR'];
    $ip_len=strlen($ip);
    function get_city($ip)
    {
    $xml_encoding = ‘windows-1251′;
    $in_charset = ‘UTF-8′;
    $out_charset = ‘windows-1251′;
    $xml_query = “”.$ip.”";
    $xml_response = “”;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, ‘http://194.85.91.253:8090/geo/geo.html’);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_query);
    $xml_response .= curl_exec($ch);
    curl_close($ch);
    return $xml_response;;
    }

    function get_region($ip)
    {
    $xml_encoding = ‘windows-1251′;
    $in_charset = ‘UTF-8′;
    $out_charset = ‘windows-1251′;
    $xml_query = “”.$ip.”";
    $xml_response = “”;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, ‘http://194.85.91.253:8090/geo/geo.html’);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_query);
    $xml_response .= curl_exec($ch);
    curl_close($ch);
    return $xml_response;;
    }

    function ln_str_encode($str, $in_charset, $out_charset)
    {

    if (function_exists(’mb_convert_encoding’))
    {
    return mb_convert_encoding($str, $out_charset, $in_charset);
    }
    else
    {
    return iconv($in_charset, $out_charset, $str);
    }

    }

    $city=get_city($ip);
    $minus=$ip_len+102;
    $length=strlen($city)-$minus;
    $start=$ip_len+76;
    $city=iconv_substr ($city, $start , $length);

    $region=get_region($ip);
    $minus=$ip_len+106;
    $length=strlen($region)-$minus;
    $start=$ip_len+78;
    $region=iconv_substr ($region, $start , $length);
    ?>

    на выходе: город - $city, регион - $region.

  29. 29
    Администратор ответил:
    вопщем я так и не разобрался как их xml ответа вычленить нужную информацию… сделал по топорному. (мне нужны были только город и регион)

    Для того чтобы получать только город и регион, запрос должен выглядеть следующим образом:
    <ipquery>
    <fields>
    <city/>
    <region/>
    </fields>
    <ip-list>
    <ip>1.2.3.4</ip>
    <ip>5.6.7.8</ip>
    ….
    <ip>9.10.11.12</ip>
    </ip-list>

  30. 30
    Scorpio ответил:

    2Администратор:

    Спасибо огромное за сервис! Бесценная информация для анализа аудитории сайта по регионам.
    Однако не помешалобы в ответе вашего шлюза еще один параметр - название провайдера (ISP)
    как например выводится в ответе на запрос http://www.vline.ru/ip/?ip=x.x.x.x
    (поля netname и desc или хотябы только netname)

    Есть ли подобная информация в Вашей базе?
    Если да, то сможете ли Вы ее возвражать в ответе на запрос?
    Не планируете ли Вы создать HTTP-GET запрос по единственному IP по образцу приведенному мной выше? например чтото вроде http://194.85.91.253:8090/?ip=x.x.x.x
    Планируете ли Вы ввести ограничение на кол-во запрос с одного IP за единицу времени?
    Если да, то какой лимит будет установлен?

Страницы: [1] 2 3 4 5 » Показать все комментарии

Комментировать:

© 2007-2015 IpGeoBase