web-dev-qa-db-ja.com

Django、IPロケーションを取得

IPアドレスからユーザーの場所を検出して、ユーザーをWebサイトの特定の場所にリダイレクトしたいと思います。

Django 1.1.1でこれを達成するための最良の方法は何でしょうか?

ありがとう

編集:ヨーロッパの都市ベースのロケーションが必要です。

25
Hellnar

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 物事を非常に詳細に説明します。それらを完全に読み通すのに少し時間がかかります。

33
Nick Presta

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

ケーキ、そしてそれは多くの(すべてではない)使用のために無料です。

MaxMind.com に移動し、 わかりやすい手順 に従います。開始から終了まで、これをDjangoアプリで実行するのに約30分かかりました。既知のIPでいくつかのテストを行いましたが、それらはvery無料版でも正確です。

3
Peter Rowell

これは、 DjangoSnippets ;からの1つの解決策です。ところで、以下のコードが 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 からのメモ: "リクエスト数が10.000未満の場合、個人またはビジネスを問わず、APIの使用は無料です。暦日ごと。単一のリンクでWorldIPデータベースにクエリを実行できるシンプルで強力なAPI。」

ユーザーの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が特定のブロックにあるかどうかをテストする場合は、 SubnetTree ライブラリfor Pythonが役立ちます。

1
David Underhill

いくつかの無料サービスに基づいています。

高速ではありませんが、無料のサービスをさらに追加できます。

設定:

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
0
Sasori Olkof