我们建议使用哪种Python方法检查whois数据库记录?

时间:2020-03-05 18:49:35  来源:igfitidea点击:

我正在尝试启动并运行实际上需要检查Whois数据库的Web服务。我现在正在做的事情很丑陋,我想尽可能地避免它:我调用gwhois命令并解析其输出。丑陋的。

我进行了一些搜索,以尝试找到一种执行此任务的pythonic方法。通常,我没有太多的东西,这个旧的讨论列表链接可以检查域是否存在。并不是我一直在寻找的东西……但是,仍然是最好的答案Google给我的其他所有东西只是一堆没有答案的问题。

你们当中有人成功建立并运行某种方法吗?我非常感谢一些技巧,还是我应该以开放源码的方式,独自坐下来编写一些代码? :)

解决方案

回答

另一种方法是使用urllib2模块来解析其他页面的whois服务(存在许多类似网站)。但这似乎更像是我们现在所做的hack,并且会使我们依赖于我们选择的任何whois网站,这很糟糕。

我讨厌这么说,但是除非我们想在程序中重新实现" whois"(这将重新发明轮子),否则在操作系统上运行" whois"并解析输出(即我们现在正在做的事情)似乎是正确的方法。

回答

解析另一个网页不会那么糟糕(假设他们的html不会很糟糕),但是如果他们失望了,那实际上会把我绑在他们身上,我就失望了:)

实际上,我在sourceforge上找到了一些旧项目:rwhois.py。令我感到有些害怕的是,它们的最新更新是2003年的。但是,它似乎是重新实现我现在所做的工作的好地方...好吧,无论如何,我感到无奈地发布了指向该项目的链接,供进一步参考。

回答

使用命令行实用程序执行所需的操作没有错。如果我们在服务周围包装好包装,则可以根据需要实现内部结构!例如:

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端口(43)上的whois服务器,发送查询,读取回复中的所有数据并解析它们。为了使生活更轻松,我们可以使用telnetlib.Telnet类(即使whois协议比telnet协议简单得多),也可以使用普通套接字。

棘手的部分:

  • 我们会问哪个whois服务器? RIPE,ARIN,APNIC,LACNIC,AFRINIC,JPNIC,VERIO等LACNIC可能是一个有用的后备,因为它们倾向于用有用的数据回复其域外的请求。
  • 每个Whois服务器的确切选项和参数是什么?有些提供帮助,有些则没有。通常,纯域名无需任何特殊选项即可使用。

回答

import socket
socket.gethostbyname_ex('url.com')

如果返回gaierror,我们知道它未在任何DNS中注册

回答

这是一个对我有用的即用型解决方案;为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' ] )

回答

看这个:
http://code.google.com/p/pywhois/

pywhois Python模块,用于检索域的WHOIS信息

目标:
创建一个简单的可导入Python模块,该模块将为给定域生成已解析的WHOIS数据。
能够提取所有流行的TLD(com,org,net等)的数据
直接查询WHOIS服务器,而不是像许多其他服务一样通过中间Web服务。
适用于Python 2.4及更高版本,无外部依赖关系

例子:

>>> import pywhois
>>> w = pywhois.whois('google.com')
>>> w.expiration_date
['14-sep-2011']
>>> w.emails
['[email protected]',
 '[email protected]',
 '[email protected]',
 '[email protected]']
>>> print w
...