我们建议使用哪种Python方法检查whois数据库记录?
我正在尝试启动并运行实际上需要检查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 ...