Нет ничего неправильно с использованием утилиты командной строки, чтобы сделать то, что Вы хотите. При помещении хорошей обертки вокруг сервиса можно реализовать внутренности однако, Вы хотите! Например:
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 очевидным для Вашего клиентского кода.
Практичность бьет чистоту - это - то, что является Pythonic.:)
Я не знаю, делает ли gwhois что-то специальное с выводом сервера; однако, можно явно соединиться с whois сервером на порте whois (43), отправить запрос, считать все данные в ответе и проанализировать их. Для создания жизни немного легче Вы могли использовать telnetlib. Класс Telnet (даже если whois протокол намного более прост, чем протокол telnet) вместо простых сокетов.
Хитрые части:
При парсинге другой веб-страницы woulnd't быть как плохо (принимающий их HTML woulnd't быть очень плохим), но это на самом деле связало бы меня с ними - если они снижаются, я снижаюсь :)
На самом деле я нашел некоторый старый проект на SourceForge: rwhois.py. Что пугает меня, немного то, что их последнее обновление с 2003. Но, это, могло бы казаться, как хорошее место запустило бы переопределение того, что я делаю прямо сейчас... Ну, я чувствовал obligued для регистрации ссылки на этот проект так или иначе, только для дальнейшей ссылки.
Другой способ сделать это состоит в том, чтобы использовать urllib2
модуль для парсинга whois сервиса некоторой другой страницы (много сайтов как этот существуют). Но это походит еще на большее количество взлома, что, что Вы делаете теперь, и дал бы Вам зависимость от любого whois сайта, который Вы выбрали, который плох.
Я очень не хочу сказать это, но если Вы не хотите повторно реализовать whois
в Вашей программе (который изобрел бы велосипед), работая whois
на ОС и парсинге вывода (т.е. что Вы делаете теперь) походит на правильный способ сделать это.
вот готовое решение, которое мне подходит; написан для Python 3.1 (при обратном переносе на Py2.x особое внимание уделяйте различиям между байтами и текстом Unicode). единственной точкой доступа является метод 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' ] )
import socket
socket.gethostbyname_ex('url.com')
если он возвращает ошибку, вы знаете, что она не зарегистрирована ни в одном DNS