您建议使用哪种 Python 方式来检查 whois 数据库记录?
题
我正在尝试启动并运行一个实际上需要检查 whois 数据库的网络服务。我现在正在做的事情很丑陋,我想尽可能避免它:我调用 gwhois 命令并解析其输出。丑陋的。
我做了一些搜索,试图找到一种Python式的方法来完成这项任务。一般来说我什么也没得到—— 这个旧的讨论列表链接 有一种方法可以检查域是否存在。完全不是我想要的......但这仍然是谷歌给我的最好的答案——其他一切都只是一堆未解答的问题。
你们中有人成功地启动并运行了某种方法吗?我非常感谢一些提示,或者我应该以开源方式进行,坐下来自己编写一些代码?:)
解决方案
使用命令行实用程序来执行您想要的操作没有任何问题。如果您在服务周围放置了一个很好的包装,您就可以按照您想要的方式实现内部结构!例如:
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。:)
其他提示
看这个:http://code.google.com/p/pywhois/
pywhois - 用于检索域的 WHOIS 信息的 Python 模块
目标:- 创建一个简单的可导入 Python 模块,它将为给定域生成已解析的 WHOIS 数据。- 能够提取所有流行的TLD(com,org,net,...)的数据 - 直接查询A WHOIS服务器,而不是像许多其他人一样浏览中间Web服务。- 适用于 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
...
在我自己搜索python whois库的过程中发现了这个问题。
不知道我同意Cdleary的回答,即使用包装命令的图书馆始终是最好的方法 - 但我可以看到他的原因。
专业人士:cmd-line whois 处理所有艰苦的工作(套接字调用、解析等)
缺点:不可携带;模块可能无法工作,具体取决于底层 whois 命令。速度较慢,因为除了 whois 命令之外还运行命令和最有可能的 shell。影响如果不是Unix(Windows),不同的UNIX,较旧的UNIX或较旧的WHOIS命令
我正在寻找一个可以处理 whois IP 查找的 whois 模块,并且我对编写自己的 whois 客户端不感兴趣。
以下是我(稍微)尝试过的模块以及有关它的更多信息:
pywhoisapi:
- 家: http://code.google.com/p/pywhoisapi/
- 设计:REST 客户端访问 ARIN whois REST 服务
- 优点:能够处理IP地址查找
- 缺点:能够从其他 RIR 的 whois 服务器中提取信息吗?
批量域名查询
- 家: http://pypi.python.org/pypi/BulkWhois/0.2.1
- 设计:telnet 客户端从 RIR(?) 访问 whois telnet 查询接口
- 优点:能够处理IP地址查找
- 缺点:能够从其他 RIR 的 whois 服务器中提取信息吗?
pywhois:
- 家: http://code.google.com/p/pywhois/
- 设计:REST 客户端访问 RRID whois 服务
- 优点:访问多个 RRID;有 python 3.x 分支
- 缺点:似乎不处理 IP 地址查找
蟒蛇-whois:
- 家: http://code.google.com/p/python-whois/
- 设计:包装“whois”命令
- 缺点:似乎不处理 IP 地址查找
whoisclient - python-whois 的分支
- 家: http://gitorious.org/python-whois
- 设计:包装“whois”命令
- 依赖于取决于:IPy.py
- 缺点:似乎不处理 IP 地址查找
更新:我最终使用 pywhoisapi 进行反向 IP 查找
下面是用 Python 重新实现的 whois 客户端:http://code.activestate.com/recipes/577364-whois-client/
我不知道 gwhois 是否对服务器输出做了一些特殊的事情;但是,您可以简单地连接到端口 whois (43) 上的 whois 服务器,发送查询,读取回复中的所有数据并解析它们。为了让生活更轻松一些,您可以使用 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 时,请特别注意字节/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' ] )