28.10.2009

Как определить город посетителя (определение адреса по ip)

Все хорошие сайты умеют определять адрес, вернее, город, в котором живет посетитель. И делается это, понятно, по ip-адресу. Только вот кто откуда берет географические привязки ip? Лично я решил использовать сервис IpGeoBase. Он позволяет скачать базу целиком или же использовать xml-сервис. Я предпочел пока второй вариант, чтобы не заморачиваться с ежедневным выкачиванием базы. Понятно, что когда поток посетителей у меня возрастет до небывалых высот, я буду выкачивать базу. А пока у меня это работает очень быстро и выглядит так (код на Питоне 2.6):

#coding=utf-8

def getGeoData(ip):
  """Получить город по ip-адресу (адрес предается как строка).
  Возвращает словарь с элементами-строками city, region, district
  "
""

  import httplib
  import re
  from xml.dom.minidom import parseString

  conn = httplib.HTTPConnection("194.85.91.253:8090")
  conn.request("POST", "/geo/geo.html", \
    "<ipquery><fields><all/></fields><ip-list><ip>" + ip + \
    "</ip></ip-list></ipquery>")
  resp = conn.getresponse()

  data = resp.read()
  conn.close()

  # если ничего не найдено
  if re.search("<message>Not found</message>", data):
    return None

  dom = parseString(data)
  city = dom.documentElement.getElementsByTagName('city')[0]\
    .firstChild.nodeValue
  region = dom.documentElement.getElementsByTagName('region')[0]\
    .firstChild.nodeValue
  district = dom.documentElement.getElementsByTagName('district')[0]\
    .firstChild.nodeValue

  return {'city' : city, 'region' : region, 'district' : district}


Теперь вопрос остальным: кто как справляется с этой задачей?

UPD: иногда сервис неверно определяет адрес по ip, потому что некоторые провайдеры используют общий DHCP для всех регионов, или же информация об адресах еще не собрана. Войдя на IpGeoBase, можно указать свой правильный адрес, если по ip он определился неверно.

4 комментария:

Иван комментирует...

Привет, смотри тут уже есть приложение http://ipgeobase.ru/cgi-bin/Software.cgi для django

gt_rocker комментирует...

Ясно. Вы пошли дальше и закачиваете себе базу дипазонов целиком, и уже в ней ищете город по ip-адресу. Мне понравилось, как написано. А в чем специфика работы только под 1.2+ ?

Иван комментирует...

Специфика из-за postgres для поля bigint

Иван комментирует...

BigIntegerField есть только в 1.2+