Джанго, Получить IP местоположение
Я хотел бы перенаправить своих пользователей в определенные области местоположения на моем веб-сайте, определяя их местоположение по их IP-адресу.
Каков наилучший способ добиться этого под Django 1.1.1?
Спасибо
Редактировать: Я хочу, чтобы город базировался на Европе.
8 ответов
GeoDjango выглядит так, как будто он подойдет вам. Я не уверен, как именно вы бы хотели направлять пользователей, но используя GeoIP API, вы можете сделать что-то вроде:
from django.contrib.gis.utils import GeoIP
g = GeoIP()
ip = request.META.get('REMOTE_ADDR', None)
if ip:
city = g.city(ip)['city']
else:
city = 'Rome' # default city
# proceed with city
Документы объясняют вещи очень подробно; Я бы уделил минуту, чтобы прочитать их полностью.
GeoIP уже упоминался, но я считаю, что pygeoip менее сложен в установке и не представляет сложности, если вы хотите встроить его в свое приложение вместо установки в пакеты сайта Python. Тем не менее, он прекрасно работает с бесплатными базами данных MaxMind, например, GeoLite City.
Пример использования (почти такой же, как для GeoIP):
>>> import pygeoip
>>> gi = pygeoip.GeoIP(GEOIP_DATABASE, pygeoip.GEOIP_STANDARD)
>>> gi.record_by_addr(ip)
{'country': '...', 'country_code': '...', ...}
Это одно решение от DjangoSnippets; Кстати, не уверен, почему код ниже не использует urlparse; но это можно исправить:-)
(Глядя на другие ответы, кажется, у вас есть много вариантов для выбора. Этот вариант может быть не предпочтительным, поскольку он опирается на бесплатную стороннюю службу.)
from urllib2 import urlopen, Request
import re, socket
from django.conf import settings
domain_re = re.compile('^(http|https):\/\/?([^\/]+)')
domain = domain_re.match(settings.SITE_URL).group(2)
def getUserCountry(ip):
url = "http://api.wipmania.com/" + ip + "?" + domain
socket.setdefaulttimeout(5)
headers = {'Typ':'django','Ver':'1.1.1','Connection':'Close'}
try:
req = Request(url, None, headers)
urlfile = urlopen(req)
land = urlfile.read()
urlfile.close()
return land[:2]
except Exception:
return "XX"
Примечание от WIPmania: "Использование API бесплатно для любых целей, личных или деловых, если вы делаете менее 10.000 запросов в календарный день. Простой, но мощный API, позволяющий запрашивать базу данных WorldIP с помощью одной ссылки".
Кусок пирога, и это бесплатно для многих (но не всех) пользователей.
Зайдите на MaxMind.com и следуйте дружеским инструкциям. Начало до конца заняло у меня около 30 минут, чтобы запустить его в приложении Django. Я провел ряд тестов на известных IP-адресах, и они очень точные, даже в бесплатной версии.
На основе некоторых бесплатных сервисов.
это не быстро, но вы можете добавить дополнительные бесплатные услуги:
настройки:
IPCOUNTRY_APYKEY = [
{# free tier 2 querys per second
"url": "http://api.ipinfodb.com/v3/ip-country/?ip={ip}&key={key}&format=json",
"params": {
"key": "****************************",
},
"fieldname": "countryCode",
},
{# free tier 1.500 queries per day
"url": "https://api.ipdata.co/{ip}?api-key={key}",
"params": {
"key": "*************************",
},
"fieldname": "country_code",
},
{# free tier 10.000 queries per month and https is not suported in free tier
"url": "http://api.ipstack.com/{ip}?access_key={key}",
"params": {
"key": "********************",
},
"fieldname": "country_code",
},
]
КОД:
import json
import urllib3
from django.conf import settings
for service in settings.IPCOUNTRY_APYKEY:
url = service["url"].format(ip=ip,**service["params"])
headers = {'Type': 'django', 'Ver': '1.1.1', 'Connection': 'Close'}
urllib3.disable_warnings()
http_call = urllib3.PoolManager()
try:
r = http_call.request('GET', url, headers=headers, timeout=1.0)
if r.status == 200:
json_response = json.loads(r.data.decode("utf-8"))
print(json_response[service["fieldname"]])
except Exception as e:
pass
return None
Вы можете создать представление, которое получает IP-адрес пользователя, а затем выдает HTTP-перенаправление, которое заставит их браузер загрузить нужную страницу:
def redirect_based_on_ip(request):
ip = request.meta['REMOTE_ADDR']
if ip == SOMETHING:
return HttpResponseRedirect('/something')
elif ip == SOMETHING_ELSE:
return HttpResponseRedirect('/something_else')
# ...
Библиотека SubnetTree для Python может оказаться полезной, если вы хотите проверить, находится ли IP в определенном блоке.
Я сделал ТАК- ответ, где я использую Cloudflare CDN, они предоставляют дополнительный заголовок с местоположением GEO каждого посетителя. Преимущество в том, что нам не нужно устанавливать какую-либо внешнюю библиотеку или выполнять какие-либо вызовы API. Перенаправление может быть выполнено с помощью промежуточного программного обеспечения Django.
Вы можете добиться этого, используя библиотеку IP2Location Python и базу данных IP2Location BIN. Сначала приобретите коммерческую базу данных IP2Location по адресу https://www.ip2location.com/database/ip2location или загрузите бесплатную базу данных IP2Location LITE по адресу https://lite.ip2location.com/ . А также установите библиотеку Python IP2Location с помощью этой команды:pip install IP2Location
После этого откройте файл views.py и добавьте в файл следующий код:
from django.http import HttpResponse
from django.shortcuts import redirect
import IP2Location
database = IP2Location.IP2Location(YOUR_DATABASE_PATH)
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
if ip == '127.0.0.1': # Only define the IP if you are testing on localhost.
ip = '8.8.8.8'
return ip
def redirect_view(request):
ip = get_client_ip(request)
rec = database.get_all(ip)
if rec.city == 'London': # Or any other city name
response = redirect('PATH_REDIRECT_TO')
return response
def redirectsucess_view(request):
return HttpResponse('Welcome!')
После этого откройте urls.py и добавьте в список urlpatterns следующие коды:
path('redirect/', views.redirect_view),
path('PATH_REDIRECT_TO/', views.redirectsucess_view)