призрачный форум

www.prizrak.ws

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » www.prizrak.ws » Программирование » определение страны по Ip-адресу>>


определение страны по Ip-адресу>>

Сообщений 1 страница 8 из 8

1

определение страны по Ip-адресу
При сборе статистики посещения web-страниц часто собирается информация (info) о количестве посетителей из разных стран. Как правило, страну определяют по домену первого уровня. Но такая информация (info) не всегда соответствует действительности, особенное учитывая нынешнюю тендецию использовать национальные домены co, tv не по назначению. Кроме того, как быть с доменами общего пользования net, org, com и др.? С IP-адресами, для которых нет записей в реверсной зоне? Ну и, наконец, определение доменного имени отнимает заметное количество времени.

Приведенный в статье код распространяется под лицензией в стиле Python, то есть может быть использован для любых (в том числе коммерческих целей) при условии сохранения замечания об авторском праве Copyright © 2002, Denis S. Otkidach <ods@ods.pp.ru>.

Данные о регистрации диаппазонов IP-адресов хранятся в базах данных whois. Чтобы предоставить возможность общественности анализировать трафик, RIPE NCC, ARIN и APNIC не реже, чем раз в месяц, делают сокращенные "снимки" своих баз данных. Именно из этих данных мы и составим локальную базу.

Но сначала нужно эффективно оргазовать хранение данных для диаппазонов IP-адресов, чтобы обеспечить к ним быстрый доступ. За основу возмем BTree базу BerkleyDB, доступ к которой обеспечивает функция btopen() из стандартного модуля bsddb. В качестве ключей будем использовать начало диаппазона IP-адресов, а в качестве значений — его конец и дополнительную информацию. Ключи и значения в bsddb должны быть строками. Кроме того, необходимо обеспечить упорядоченность ключей. Для этого очень хорошо подходит функции inet_aton и inet_ntoa из модуля socket.

from bsddb import btopen
from socket import inet_aton, inet_ntoa

class IPRangeDB:

def __init__(self, filename, mode='r'):
self.__db = btopen(filename, mode)

def close(self):
self.__db.close()

def _locate(self, ip):
db = self.__db
try:
first, record = db.set_location(ip)
except KeyError:
try:
first, record = db.last()
except KeyError:
raise KeyError(inet_ntoa(ip))
else:
if first!=ip:
first, record = db.previous()
assert first<=ip
return first, record

def __getitem__(self, ip_str):
ip = inet_aton(ip_str)
first, record = self._locate(ip)
last = record[:4]
assert last>=first
if ip<=last:
return self.unpack(record[4:])
else:
raise KeyError(ip_str)

def add(self, first_str, last_str, info):
first = inet_aton(first_str)
last = inet_aton(last_str)
try:
db_first, record = self._locate(last)
except KeyError:
pass
else:
db_last = record[:4]
if first<=db_last:
raise ValueError(
'Range %s-%s intersects ' % (first_str, last_str) +
'with existing entry %s-%s' %
(inet_ntoa(db_first), inet_ntoa(db_last)))
self.__db[first] = last+self.pack(info)

def pack(self, info):
return info

def unpack(self, info):
return info

Метод _locate() ищет запись с максимальной нижней границей, меньшей или равной IP-адресу, переданному в качестве аргумента. Метод __getitem__() позволяет использовать экземпляры класса IPRangeDB аналогично словарям: db[ip] вернет информацию о диаппазоне, в который входит адрес ip. Использовать интерфейс словаря для записи врядли будет хорошей идеей, так как запись создается одна для всего диаппазона. Чтобы избежать путаницы, добавление записей реализовано через метод add(). И, наконец, пара методов pack() и unpack() определены, чтобы производный класс можно было легко адоптировать для хранения произвольной информации, метод pack() должен преобразовывать объект в строку.

>>> db = IPRangeDB('test.db', 'c')
>>> db.add('10.0.0.0', '10.255.255.255', 'Наша локальная сеть')
>>> print db['10.1.2.3']
Наша локальная сеть
>>> print db['123.45.67.89']
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "ip2cc.py", line 38, in __getitem__
raise KeyError(ip_str)
KeyError: 123.45.67.89

Осталось дело за малым: определить методы для наполнения базы данных.

from urllib import urlopen
from xreadlines import xreadlines
from time import strptime
import struct

class CountryByIP(IPRangeDB):

sources = {
'arin' : ('ftp://ftp.arin.net/pub/stats/arin/', 'arin.%Y%m%d'),
'ripencc': ('ftp://ftp.ripe.net/ripe/stats/', 'ripencc.%Y%m%d'),
'apnic' : ('ftp://ftp.apnic.net/pub/stats/apnic/', 'apnic-%Y-%m-%d')
}

def fetch(self):
for name in self.sources:
fp = self.__openRecent(name)

for line in xreadlines(fp):
parts = line.strip().split('|')
if len(parts)==7 and parts[2]=='ipv4' and
parts[6] in ('allocated', 'assigned') and
name==parts[0]:
first = parts[3]
first_int = struct.unpack('!i', inet_aton(first))[0]
last_int = first_int+int(parts[4])-1
last = inet_ntoa(struct.pack('!i', last_int))
try:
self.add(first, last, parts[1].upper())
except ValueError:
pass

def __openRecent(self, name):
uri, format = self.sources[name]
files = []
for line in xreadlines(urlopen(uri)):
file = line.split()[-1]
try:
dt = strptime(file, format)
except ValueError:
pass
else:
files.append((dt, file))
files.sort()
return urlopen(uri+files[-1][1])

Метод __openRecent находит самый свежий "снимок" и возвращает файловый объект. Дата "снимка" определяется по имени файла по шаблону из словаря источников sources. Метод fetch анализирует данные, выбирает необходимое и добавляет в базу. Использование модуля xreadlines позволяет анализировать данные по мере поступления.

Теперь можно наполнить базу

>>> db = CountryByIP('test.db', 'n')
>>> db.fetch()

и использовать

>>> from socket import gethostbyname
>>> db[gethostbyname('python.org')]
'NL'

Преобразование кода A2 в название страны по таблице ISO3166 пусть останется вам в качестве упражнения.

Автор (C): Д.С.Откидач
Источник: iso.ru

Подпись автора

Я Хранитель Свеч на границе Тьмы Свет ковал мой меч для своей войны…


www.prizrak.ws Аниме Форум - для общения любителей аниме (японской анимации), манги и хентая. Новости, статьи по темам: безопасность, хакерство, программы. Игры и софт для WinOS, PocketPC, Linux/Unix и др. Архив игр, фильмов DVD, музыки mp3 и программного обеспечения. Теги: скачать anime, скачать мангу, скачать хентай, скачать яой, скачать юри, скачать аниме обои картинки, скачать музыку mp3, скачать фильмы dvd, скачать софт, скачать программы, скачать игры ^__^

0

2

Пригодится =) Но я За Анонимность....

0

3

Спс,теперь буду знать)

Подпись автора

работает всё! - вот твоя подпись))

0

4

Cпасибо большое за информацию!)

Подпись автора

Life is game...

0

5

ну....не знаю зачем это надо, но может в общем пригодиться)

Подпись автора

如果你隨地吐痰的背部,然後你是未來  (если вам плюют в спину, значит вы впереди)

Член Клуба [Антияой]

0

6

В качестве теории с пивом пойдет

Подпись автора

kill yourself - save the planet

0

7

В любом случаи интернет - большая помойка! И это не скоро измениться!

Подпись автора

С уважением к людям, Александр Э!

Помогите протестить прогу курсового проекта!!! Всё прост как 2+2
Подробности...

Все пожертвования сюда:
R353735646170 E213104065381 Z208501919034 B470625518011 Y166475683858
Яндекс - (yandex).Деньги 41001322905771

Член клуба М.Н.К.

0

8

Сорри за оффтоп

Знаете Админы (буксов например) пугают: "проверяю кликы по сцылкам по IP !!! Бу-га-га-га"

Вопрос: эт как? чё они делаютъ для этого?

Подпись автора

WMY: Y116199046192
WMB: B401884347077
WMR: R213292158051

0


Вы здесь » www.prizrak.ws » Программирование » определение страны по Ip-адресу>>