<p>I'm trying to get a webservice up and running that actually requires to check whois databases. What I'm doing right now is ugly and I'd like to avoid it as much as I can: I call gwhois command and parse its output. Ugly.</p>

<p>I did some search to try to find a pythonic way to do this task. Generally I got quite much nothing - <a href="http://mail.python.org/pipermail/python-list/2000-March/028122.html" rel="noreferrer">this old discussion list link</a> has a way to check if domain exist. Quite not what I was looking for... But still, it was best anwser Google gave me - everything else is just a bunch of unanwsered questions.</p>

<p>Any of you have succeeded to get some method up and running? I'd very much appreciate some tips, or should I just do it the opensource-way, sit down and code something by myself? :) </p>

[{'answer_id': 50413, 'author': 'Justin Standard', 'author_id': 92, 'author_profile': 'https://Stackoverflow.com/users/92', 'pm_score': 0, 'selected': False, 'text': "<p>Another way to do it is to use <code>urllib2</code> module to parse some other page's whois service (many sites like that exist).  But that seems like even more of a hack that what you do now, and would give you a dependency on whatever whois site you chose, which is bad.</p>\n\n<p>I hate to say it, but unless you want to re-implement <code>whois</code> in your program (which would be re-inventing the wheel), running <code>whois</code> on the OS and parsing the output (ie what you are doing now) seems like the right way to do it.</p>\n"}, {'answer_id': 50423, 'author': 'kender', 'author_id': 4172, 'author_profile': 'https://Stackoverflow.com/users/4172', 'pm_score': 0, 'selected': False, 'text': '<p>Parsing another webpage woulnd\'t be as bad (assuming their html woulnd\'t be very bad), but it would actually tie me to them - if they\'re down, I\'m down :) </p>\n\n<p>Actually I found some old project on sourceforge: <a href="http://sourceforge.net/projects/rwhois/" rel="nofollow noreferrer">rwhois.py</a>. What scares me a bit is that their last update is from 2003. But, it might seem as a good place to start reimplementation of what I do right now... Well, I felt obligued to post the link to this project anyway, just for further reference.</p>\n'}, {'answer_id': 55385, 'author': 'cdleary', 'author_id': 3594, 'author_profile': 'https://Stackoverflow.com/users/3594', 'pm_score': 4, 'selected': True, 'text': '<p>There\'s nothing wrong with using a command line utility to do what you want. If you put a nice wrapper around the service, you can implement the internals however you want! For example:</p>\n\n<pre><code>class Whois(object):\n    _whois_by_query_cache = {}\n\n    def __init__(self, query):\n        """Initializes the instance variables to defaults. See :meth:`lookup`\n        for details on how to submit the query."""\n        self.query = query\n        self.domain = None\n        # ... other fields.\n\n    def lookup(self):\n        """Submits the `whois` query and stores results internally."""\n        # ... implementation\n</code></pre>\n\n<p>Now, whether or not you roll your own using urllib, wrap around a command line utility (like you\'re doing), or import a third party library and use that (like <a href="https://stackoverflow.com/questions/50394#50423">you\'re saying</a>), this interface stays the same.</p>\n\n<p>This approach is generally not considered ugly at all -- <strong>sometimes command utilities do what you want and you should be able to leverage them</strong>. If speed ends up being a bottleneck, your abstraction makes the process of switching to a native Python implementation transparent to your client code.</p>\n\n<p><a href="http://www.python.org/dev/peps/pep-0020/" rel="nofollow noreferrer">Practicality beats purity</a> -- that\'s what\'s Pythonic. :)</p>\n'}, {'answer_id': 68218, 'author': 'tzot', 'author_id': 6899, 'author_profile': 'https://Stackoverflow.com/users/6899', 'pm_score': 1, 'selected': False, 'text': "<p>I don't know if gwhois does something special with the server output; however, you can plainly connect to the whois server on port whois (43), send your query, read all the data in the reply and parse them. To make life a little easier, you could use the telnetlib.Telnet class (even if the whois protocol is much simpler than the telnet protocol) instead of plain sockets.</p>\n\n<p>The tricky parts:</p>\n\n<ul>\n<li>which whois server will you ask? RIPE, ARIN, APNIC, LACNIC, AFRINIC, JPNIC, VERIO etc LACNIC could be a useful fallback, since they tend to reply with useful data to requests outside of their domain.</li>\n<li>what are the exact options and arguments for each whois server? some offer help, others don't. In general, plain domain names work without any special options.</li>\n</ul>\n"}, {'answer_id': 2408136, 'author': 'Ryan', 'author_id': 289525, 'author_profile': 'https://Stackoverflow.com/users/289525', 'pm_score': -1, 'selected': False, 'text': "<pre><code>import socket\nsocket.gethostbyname_ex('url.com')\n</code></pre>\n\n<p>if it returns a gaierror you know know it's not registered with any DNS</p>\n"}, {'answer_id': 2410537, 'author': 'flow', 'author_id': 256361, 'author_profile': 'https://Stackoverflow.com/users/256361', 'pm_score': 0, 'selected': False, 'text': "<p>here is a ready-to-use solution that works for me; written for Python 3.1 (when backporting to Py2.x, take special care of the bytes / Unicode text distinctions). your single point of access is the method <code>DRWHO.whois()</code>, which expects a domain name to be passed in; it will then try to resolve the name using the provider configured as <code>DRWHO.whois_providers[ '*' ]</code> (a more complete solution could differentiate providers according to the top level domain). <code>DRWHO.whois()</code> will return a dictionary with a single entry <code>text</code>, which contains the response text sent back by the WHOIS server. Again, a more complete solution would then try and parse the text (which must be done separately for each provider, as there is no standard format) and return a more structured format (e.g., set a flag <code>available</code> which specifies whether or not the domain looks available). have fun!</p>\n\n<pre><code>##########################################################################\nimport asyncore as                                   _sys_asyncore\nfrom asyncore import loop as                         _sys_asyncore_loop\nimport socket as                                     _sys_socket\n\n\n\n##########################################################################\nclass _Whois_request( _sys_asyncore.dispatcher_with_send, object ):\n  # simple whois requester\n  # original code by Frederik Lundh\n\n  #-----------------------------------------------------------------------\n  whoisPort = 43\n\n  #-----------------------------------------------------------------------\n  def __init__(self, consumer, host, provider ):\n    _sys_asyncore.dispatcher_with_send.__init__(self)\n    self.consumer = consumer\n    self.query    = host\n    self.create_socket( _sys_socket.AF_INET, _sys_socket.SOCK_STREAM )\n    self.connect( ( provider, self.whoisPort, ) )\n\n  #-----------------------------------------------------------------------\n  def handle_connect(self):\n    self.send( bytes( '%s\\r\\n' % ( self.query, ), 'utf-8' ) )\n\n  #-----------------------------------------------------------------------\n  def handle_expt(self):\n    self.close() # connection failed, shutdown\n    self.consumer.abort()\n\n  #-----------------------------------------------------------------------\n  def handle_read(self):\n    # get data from server\n    self.consumer.feed( self.recv( 2048 ) )\n\n  #-----------------------------------------------------------------------\n  def handle_close(self):\n    self.close()\n    self.consumer.close()\n\n\n##########################################################################\nclass _Whois_consumer( object ):\n  # original code by Frederik Lundh\n\n  #-----------------------------------------------------------------------\n  def __init__( self, host, provider, result ):\n    self.texts_as_bytes = []\n    self.host           = host\n    self.provider       = provider\n    self.result         = result\n\n  #-----------------------------------------------------------------------\n  def feed( self, text ):\n    self.texts_as_bytes.append( text.strip() )\n\n  #-----------------------------------------------------------------------\n  def abort(self):\n    del self.texts_as_bytes[:]\n    self.finalize()\n\n  #-----------------------------------------------------------------------\n  def close(self):\n    self.finalize()\n\n  #-----------------------------------------------------------------------\n  def finalize( self ):\n    # join bytestrings and decode them (witha a guessed encoding):\n    text_as_bytes         = b'\\n'.join( self.texts_as_bytes )\n    self.result[ 'text' ] = text_as_bytes.decode( 'utf-8' )\n\n\n##########################################################################\nclass DRWHO:\n\n  #-----------------------------------------------------------------------\n  whois_providers = {\n    '~isa':   'DRWHO/whois-providers',\n    '*':      'whois.opensrs.net', }\n\n  #-----------------------------------------------------------------------\n  def whois( self, domain ):\n    R         = {}\n    provider  = self._get_whois_provider( '*' )\n    self._fetch_whois( provider, domain, R )\n    return R\n\n  #-----------------------------------------------------------------------\n  def _get_whois_provider( self, top_level_domain ):\n    providers = self.whois_providers\n    R         = providers.get( top_level_domain, None )\n    if R is None:\n      R = providers[ '*' ]\n    return R\n\n  #-----------------------------------------------------------------------\n  def _fetch_whois( self, provider, domain, pod ):\n    #.....................................................................\n    consumer  = _Whois_consumer(           domain, provider, pod )\n    request   = _Whois_request(  consumer, domain, provider )\n    #.....................................................................\n    _sys_asyncore_loop() # loops until requests have been processed\n\n\n#=========================================================================\nDRWHO = DRWHO()\n\n\ndomain    = 'example.com'\nwhois     = DRWHO.whois( domain )\nprint( whois[ 'text' ] )\n</code></pre>\n"}, {'answer_id': 4078336, 'author': 'Aziz', 'author_id': 494805, 'author_profile': 'https://Stackoverflow.com/users/494805', 'pm_score': 3, 'selected': False, 'text': '<p>Look at this:\n<a href="http://code.google.com/p/pywhois/" rel="noreferrer">http://code.google.com/p/pywhois/</a></p>\n\n<p>pywhois - Python module for retrieving WHOIS information of domains</p>\n\n<p>Goal:\n- Create a simple importable Python module which will produce parsed WHOIS data for a given domain.\n- Able to extract data for all the popular TLDs (com, org, net, ...)\n- Query a WHOIS server directly instead of going through an intermediate web service like many others do.\n- Works with Python 2.4+ and no external dependencies</p>\n\n<p>Example:</p>\n\n<pre><code>&gt;&gt;&gt; import pywhois\n&gt;&gt;&gt; w = pywhois.whois(\'google.com\')\n&gt;&gt;&gt; w.expiration_date\n[\'14-sep-2011\']\n&gt;&gt;&gt; w.emails\n[\'contact-admin@google.com\',\n \'dns-admin@google.com\',\n \'dns-admin@google.com\',\n \'dns-admin@google.com\']\n&gt;&gt;&gt; print w\n...\n</code></pre>\n'}, {'answer_id': 5494113, 'author': 'Boden Garman', 'author_id': 584423, 'author_profile': 'https://Stackoverflow.com/users/584423', 'pm_score': 2, 'selected': False, 'text': '<p>Here is the whois client re-implemented in Python:\n<a href="http://code.activestate.com/recipes/577364-whois-client/" rel="nofollow">http://code.activestate.com/recipes/577364-whois-client/</a></p>\n'}, {'answer_id': 11343954, 'author': 'Lars Nordin', 'author_id': 570450, 'author_profile': 'https://Stackoverflow.com/users/570450', 'pm_score': 3, 'selected': False, 'text': '<p>Found this question in the process of my own search for a python whois library.</p>\n\n<p>Don\'t know that I agree with cdleary\'s answer that using a library that wraps\n  a command is always the best way to go - but I can see his reasons why he said this.</p>\n\n<p>Pro: cmd-line whois handles all the hard work (socket calls, parsing, etc)</p>\n\n<p>Con: not portable; module may not work depending on underlying whois command.\n       Slower, since running a command and most likely shell in addition to whois command.\n       Affected if not UNIX (Windows), different UNIX, older UNIX, or\n       older whois command</p>\n\n<p>I am looking for a whois module that can handle whois IP lookups and I am not interested in coding my own whois client.  </p>\n\n<p>Here are the modules that I (lightly) tried out and more information about it:</p>\n\n<p>pywhoisapi:</p>\n\n<ul>\n<li>Home: <a href="http://code.google.com/p/pywhoisapi/" rel="noreferrer">http://code.google.com/p/pywhoisapi/</a></li>\n<li>Design: REST client accessing ARIN whois REST service</li>\n<li>Pros: Able to handle IP address lookups</li>\n<li>Cons: Able to pull information from whois servers of other RIRs?</li>\n</ul>\n\n<p>BulkWhois</p>\n\n<ul>\n<li>Home: <a href="http://pypi.python.org/pypi/BulkWhois/0.2.1" rel="noreferrer">http://pypi.python.org/pypi/BulkWhois/0.2.1</a></li>\n<li>Design: telnet client accessing whois telnet query interface from RIR(?)</li>\n<li>Pros: Able to handle IP address lookups</li>\n<li>Cons: Able to pull information from whois servers of other RIRs?</li>\n</ul>\n\n<p>pywhois:</p>\n\n<ul>\n<li>Home: <a href="http://code.google.com/p/pywhois/" rel="noreferrer">http://code.google.com/p/pywhois/</a></li>\n<li>Design: REST client accessing RRID whois services</li>\n<li>Pros: Accessses many RRIDs; has python 3.x branch</li>\n<li>Cons: does not seem to handle IP address lookups</li>\n</ul>\n\n<p>python-whois:</p>\n\n<ul>\n<li>Home: <a href="http://code.google.com/p/python-whois/" rel="noreferrer">http://code.google.com/p/python-whois/</a></li>\n<li>Design: wraps "whois" command</li>\n<li>Cons: does not seem to handle IP address lookups</li>\n</ul>\n\n<p>whoisclient - fork of python-whois</p>\n\n<ul>\n<li>Home: <a href="http://gitorious.org/python-whois" rel="noreferrer">http://gitorious.org/python-whois</a></li>\n<li>Design: wraps "whois" command</li>\n<li>Depends on: IPy.py</li>\n<li>Cons: does not seem to handle IP address lookups</li>\n</ul>\n\n<p>Update: I ended up using pywhoisapi for the reverse IP lookups that I was doing</p>\n'}]
['https://Stackoverflow.com/questions/50394', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4172/']