【发布时间】:2011-01-14 03:44:42
【问题描述】:
我想通过从他们的 IP 地址检测他们的位置,将我的用户重定向到我网站中的特定位置区域。
在 Django 1.1.1 下实现这一目标的最佳方法是什么?
谢谢
编辑:我想要基于欧洲的城市定位。
【问题讨论】:
-
你想如何区分用户?基于国家?在大陆?说的语言?等等?
标签: django geolocation
我想通过从他们的 IP 地址检测他们的位置,将我的用户重定向到我网站中的特定位置区域。
在 Django 1.1.1 下实现这一目标的最佳方法是什么?
谢谢
编辑:我想要基于欧洲的城市定位。
【问题讨论】:
标签: django geolocation
【讨论】:
GeoIP 已经提到过,但我发现 pygeoip 安装起来更麻烦,而且如果你想将它嵌入到你的应用程序中而不是安装在 Python 的站点包中,我觉得很容易。尽管如此,它仍然适用于免费的 MaxMind 数据库,例如 GeoLite City one。
使用示例(与 GeoIP 几乎相同):
>>> import pygeoip
>>> gi = pygeoip.GeoIP(GEOIP_DATABASE, pygeoip.GEOIP_STANDARD)
>>> gi.record_by_addr(ip)
{'country': '...', 'country_code': '...', ...}
小菜一碟,许多(但不是全部)用途都是免费的。
转到MaxMind.com 并关注friendly instructions。从开始到结束,我花了大约 30 分钟在 Django 应用程序中运行它。我对已知 IP 进行了多次测试,它们非常准确,即使在免费版本中也是如此。
【讨论】:
这是一种解决方案,来自DjangoSnippets;顺便说一句,不知道为什么下面的代码不使用urlparse;但这可以修复:-)
(查看其他答案,您似乎有很多选项可供选择。此选项可能不是首选,因为它依赖于免费的第 3 方服务。)
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 的注释:“如果您每个日历日发出的请求少于 10,000 个,则可以免费使用 API 用于任何目的,无论是个人还是企业。一个简单而强大的 API,允许您通过单个链接查询 WorldIP 数据库。”
【讨论】:
user的location保存在DataBase中?
您可以创建一个获取用户 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')
# ...
如果您想测试某个 IP 是否在特定块中,您可能会发现 Python 的 SubnetTree 库很有帮助。
【讨论】:
基于一些免费服务。
速度不快,但可以添加更多免费服务:
设置:
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 150 querys per minute and https is not suported in free tier
"url": "http://ip-api.com/json/{ip}?fields=2",
"params": {},
"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",
},
{# free tier 10.000 queries per month and https is not suported in free tier
"url": "http://api.ipapi.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
【讨论】:
我在使用 Cloudflare CDN 的地方创建了 SO answer,它们为每个访问者的 GEO 位置提供了额外的标题。优点是我们不必安装任何外部库或进行任何 API 调用。重定向可以通过Django中间件实现。
【讨论】: