Какой способ Python вы бы предложили для проверки записей базы данных whois?
Вопрос
Я пытаюсь запустить веб-сервис, который на самом деле требует проверки баз данных whois.То, что я делаю прямо сейчас, некрасиво, и я бы хотел избегать этого, насколько это возможно:Я вызываю команду gwhois и анализирую ее выходные данные.Уродливый.
Я провел некоторый поиск, чтобы попытаться найти питонический способ выполнения этой задачи.В общем, я почти ничего не получил - эта старая ссылка на список обсуждений есть способ проверить, существует ли домен.Совсем не то, что я искал...Но, тем не менее, это был лучший ответ, который дал мне Google - все остальное - просто куча вопросов без ответов.
Кому-нибудь из вас удалось запустить какой-нибудь метод?Я был бы очень признателен за несколько советов, или мне просто сделать это с открытым исходным кодом, сесть и что-то написать самому?:)
Решение
Нет ничего плохого в использовании утилиты командной строки для выполнения того, что вы хотите.Если вы создадите красивую оболочку вокруг сервиса, вы сможете реализовать внутренние компоненты так, как захотите!Например:
class Whois(object):
_whois_by_query_cache = {}
def __init__(self, query):
"""Initializes the instance variables to defaults. See :meth:`lookup`
for details on how to submit the query."""
self.query = query
self.domain = None
# ... other fields.
def lookup(self):
"""Submits the `whois` query and stores results internally."""
# ... implementation
Теперь, независимо от того, создаете ли вы свой собственный urllib или нет, используйте утилиту командной строки (как вы делаете) или импортируйте стороннюю библиотеку и используйте ее (например ты хочешь сказать), этот интерфейс остается прежним.
Такой подход, как правило, вовсе не считается уродливым -- иногда командные утилиты делают то, что вы хотите, и вы должны быть в состоянии использовать их.Если скорость оказывается узким местом, ваша абстракция делает процесс перехода на нативную реализацию Python прозрачным для вашего клиентского кода.
Практичность превосходит чистоту -- вот что такое Питонизм.:)
Другие советы
Посмотри на это:http://code.google.com/p/pywhois/
pywhois - модуль Python для получения WHOIS-информации о доменах
Цель:- Создайте простой импортируемый модуль Python, который будет генерировать проанализированные данные WHOIS для данного домена.- Возможность извлекать данные для всех популярных TLD (com, org, net, ...) - Запрашивать WHOIS-сервер напрямую, а не через промежуточный веб-сервис, как это делают многие другие.- Работает с Python 2.4+ и не имеет внешних зависимостей
Пример:
>>> import pywhois
>>> w = pywhois.whois('google.com')
>>> w.expiration_date
['14-sep-2011']
>>> w.emails
['contact-admin@google.com',
'dns-admin@google.com',
'dns-admin@google.com',
'dns-admin@google.com']
>>> print w
...
Нашел этот вопрос в процессе моего собственного поиска библиотеки whois python.
Не знаю, согласен ли я с ответом cdleary о том, что использование библиотеки, которая обертывает команду, всегда является лучшим способом, но я могу понять его причины, по которым он это сказал.
Профессиональный:cmd-line whois выполняет всю тяжелую работу (вызовы сокетов, синтаксический анализ и т.д.)
Con:не переносной;модуль может не работать в зависимости от базовой команды whois.Медленнее, так как выполняется команда и, скорее всего, оболочка в дополнение к команде whois.Затронута, если не UNIX (Windows), другая UNIX, более старая UNIX или более старая команда whois
Я ищу модуль whois, который может обрабатывать запросы IP-адресов whois, и я не заинтересован в кодировании моего собственного клиента whois.
Вот модули, которые я (слегка) опробовал, и дополнительная информация об этом:
пьювоисапи:
- Главная: http://code.google.com/p/pywhoisapi/
- Дизайн:Клиент REST, получающий доступ к службе ARIN whois REST
- Плюсы:Способен обрабатывать запросы по IP-адресам
- Минусы:Можете ли вы получить информацию с whois-серверов других RIR?
БульКвоис
- Главная: http://pypi.python.org/pypi/BulkWhois/0.2.1
- Дизайн:клиент telnet, получающий доступ к интерфейсу запроса whois telnet из RIR (?)
- Плюсы:Способен обрабатывать запросы по IP-адресам
- Минусы:Можете ли вы получить информацию с whois-серверов других RIR?
пьюхуа:
- Главная: http://code.google.com/p/pywhois/
- Дизайн:Клиент REST, получающий доступ к службам RRID whois
- Плюсы:Доступ ко многим RRIDs;имеет ветку python 3.x
- Минусы:похоже, не обрабатывает поиск IP-адресов
python-whois:
- Главная: http://code.google.com/p/python-whois/
- Дизайн:переносит команду "whois"
- Минусы:похоже, не обрабатывает поиск IP-адресов
whoisclient - форк python-whois
- Главная: http://gitorious.org/python-whois
- Дизайн:переносит команду "whois"
- Зависит от:IPy.py
- Минусы:похоже, не обрабатывает поиск IP-адресов
Обновить:В итоге я использовал pywhoisapi для обратного поиска IP-адресов, который я выполнял
Вот клиент whois, повторно реализованный на Python:http://code.activestate.com/recipes/577364-whois-client/
Я не знаю, делает ли gwhois что-то особенное с выводом сервера;однако вы можете просто подключиться к whois-серверу через порт whois (43), отправить свой запрос, прочитать все данные в ответе и проанализировать их.Чтобы немного упростить жизнь, вы могли бы использовать telnetlib.Класс Telnet (даже если протокол whois намного проще протокола telnet) вместо обычных сокетов.
Самые сложные моменты:
- какой whois-сервер вы спросите?RIPE, ARIN, APNIC, LACNIC, AFRINIC, JPNIC, VERIO и т.д. LACNIC могут быть полезным резервным вариантом, поскольку они, как правило, отвечают полезными данными на запросы за пределами своего домена.
- каковы точные параметры и аргументы для каждого сервера whois?одни предлагают помощь, другие - нет.Как правило, обычные доменные имена работают без каких-либо специальных опций.
Другой способ сделать это - использовать urllib2
модуль для анализа службы whois какой-либо другой страницы (существует множество подобных сайтов).Но это кажется еще большим взломом, чем то, что вы делаете сейчас, и поставило бы вас в зависимость от любого выбранного вами сайта whois, а это плохо.
Мне неприятно это говорить, но если вы не хотите повторно внедрить whois
в вашей программе (которая будет заново изобретать колесо), запущенной whois
в операционной системе и разборе выходных данных (т. Е. того, что вы делаете сейчас) кажется правильным способом сделать это.
Парсинг другой веб-страницы был бы не таким плохим (при условии, что их html не будет очень плохим), но на самом деле это привязало бы меня к ним - если они не работают, я не работаю :)
Вообще-то я нашел какой-то старый проект на sourceforge: rwhois.py.Что меня немного пугает, так это то, что их последнее обновление датировано 2003 годом.Но это может показаться хорошим местом для начала переосмысления того, что я делаю прямо сейчас...Что ж, я все равно счел своим долгом разместить ссылку на этот проект, просто для дальнейшего ознакомления.
import socket
socket.gethostbyname_ex('url.com')
если он возвращает gaierror, вы знаете, что он не зарегистрирован ни в каком DNS
вот готовое к использованию решение, которое работает у меня;написано для Python 3.1 (при обратном экспорте в Py2.x обратите особое внимание на различия между байтами и текстом в Юникоде).ваша единственная точка доступа - это метод DRWHO.whois()
, который ожидает , что доменное имя будет передано в;затем он попытается разрешить имя, используя поставщика, настроенного как DRWHO.whois_providers[ '*' ]
(более полное решение могло бы дифференцировать поставщиков в зависимости от домена верхнего уровня). DRWHO.whois()
вернет словарь с одной записью text
, который содержит текст ответа, отправленный обратно сервером WHOIS.Опять же, более полное решение затем попыталось бы проанализировать текст (что должно быть сделано отдельно для каждого поставщика, поскольку стандартного формата не существует) и вернуть более структурированный формат (например, установить флаг available
который указывает, выглядит ли домен доступным).получайте удовольствие!
##########################################################################
import asyncore as _sys_asyncore
from asyncore import loop as _sys_asyncore_loop
import socket as _sys_socket
##########################################################################
class _Whois_request( _sys_asyncore.dispatcher_with_send, object ):
# simple whois requester
# original code by Frederik Lundh
#-----------------------------------------------------------------------
whoisPort = 43
#-----------------------------------------------------------------------
def __init__(self, consumer, host, provider ):
_sys_asyncore.dispatcher_with_send.__init__(self)
self.consumer = consumer
self.query = host
self.create_socket( _sys_socket.AF_INET, _sys_socket.SOCK_STREAM )
self.connect( ( provider, self.whoisPort, ) )
#-----------------------------------------------------------------------
def handle_connect(self):
self.send( bytes( '%s\r\n' % ( self.query, ), 'utf-8' ) )
#-----------------------------------------------------------------------
def handle_expt(self):
self.close() # connection failed, shutdown
self.consumer.abort()
#-----------------------------------------------------------------------
def handle_read(self):
# get data from server
self.consumer.feed( self.recv( 2048 ) )
#-----------------------------------------------------------------------
def handle_close(self):
self.close()
self.consumer.close()
##########################################################################
class _Whois_consumer( object ):
# original code by Frederik Lundh
#-----------------------------------------------------------------------
def __init__( self, host, provider, result ):
self.texts_as_bytes = []
self.host = host
self.provider = provider
self.result = result
#-----------------------------------------------------------------------
def feed( self, text ):
self.texts_as_bytes.append( text.strip() )
#-----------------------------------------------------------------------
def abort(self):
del self.texts_as_bytes[:]
self.finalize()
#-----------------------------------------------------------------------
def close(self):
self.finalize()
#-----------------------------------------------------------------------
def finalize( self ):
# join bytestrings and decode them (witha a guessed encoding):
text_as_bytes = b'\n'.join( self.texts_as_bytes )
self.result[ 'text' ] = text_as_bytes.decode( 'utf-8' )
##########################################################################
class DRWHO:
#-----------------------------------------------------------------------
whois_providers = {
'~isa': 'DRWHO/whois-providers',
'*': 'whois.opensrs.net', }
#-----------------------------------------------------------------------
def whois( self, domain ):
R = {}
provider = self._get_whois_provider( '*' )
self._fetch_whois( provider, domain, R )
return R
#-----------------------------------------------------------------------
def _get_whois_provider( self, top_level_domain ):
providers = self.whois_providers
R = providers.get( top_level_domain, None )
if R is None:
R = providers[ '*' ]
return R
#-----------------------------------------------------------------------
def _fetch_whois( self, provider, domain, pod ):
#.....................................................................
consumer = _Whois_consumer( domain, provider, pod )
request = _Whois_request( consumer, domain, provider )
#.....................................................................
_sys_asyncore_loop() # loops until requests have been processed
#=========================================================================
DRWHO = DRWHO()
domain = 'example.com'
whois = DRWHO.whois( domain )
print( whois[ 'text' ] )