【问题标题】:Django, Retrieve IP locationDjango,检索 IP 位置
【发布时间】:2011-01-14 03:44:42
【问题描述】:

我想通过从他们的 IP 地址检测他们的位置,将我的用户重定向到我网站中的特定位置区域。

在 Django 1.1.1 下实现这一目标的最佳方法是什么?

谢谢

编辑:我想要基于欧洲的城市定位。

【问题讨论】:

  • 你想如何区分用户?基于国家?在大陆?说的语言?等等?

标签: django geolocation


【解决方案1】:

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

Docs讲解的很详细;我会花点时间彻底阅读它们。

【讨论】:

【解决方案2】:

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': '...', ...}

【讨论】:

  • 这对于 Windows 来说非常实用。强烈推荐。
  • 免费下载 MaxMind 遗留数据库:Country, City
  • pygeoip 现已弃用。
【解决方案3】:

小菜一碟,许多(但不是全部)用途都是免费的。

转到MaxMind.com 并关注friendly instructions。从开始到结束,我花了大约 30 分钟在 Django 应用程序中运行它。我对已知 IP 进行了多次测试,它们非常准确,即使在免费版本中也是如此。

【讨论】:

    【解决方案4】:

    这是一种解决方案,来自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 数据库。”

    【讨论】:

    • 您可以在某处维护已知 IP 的缓存,因此不必每次有人访问您的网站时都戳 WIPmania。
    • 如何将userlocation保存在DataBase中?
    【解决方案5】:

    您可以创建一个获取用户 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 库很有帮助。

    【讨论】:

      【解决方案6】:

      基于一些免费服务。

      速度不快,但可以添加更多免费服务:

      设置:

      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
      

      【讨论】:

        【解决方案7】:

        我在使用 Cloudflare CDN 的地方创建了 SO answer,它们为每个访问者的 GEO 位置提供了额外的标题。优点是我们不必安装任何外部库或进行任何 API 调用。重定向可以通过Django中间件实现。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-19
          • 1970-01-01
          • 2013-08-23
          • 2011-02-04
          • 2022-12-20
          • 2017-04-30
          • 2011-01-03
          • 1970-01-01
          相关资源
          最近更新 更多