一、简介

RFC812定义了一个非常简单的Internet信息查询协议——WHOIS协议。其基本内容是,先向服务器的TCP端口43建立一个连接,发送查询关 键字并加上回车换行,然后接收服务器的查询结果。

世界上各级Internet管理机构秉承公开、公正、共享的原则,设立了可以查知IP地址和域名所有者登记资料的WHOIS服务器,以便所有Internet的使用者排除故障、打击网上非法活动。全世界国际区域性的IP地址管理机构有四个:ARIN、RIPE、APNIC、LACNIC,他们负责的IP地址的地理区域如下图所示。

四个国际区域性IP地址管理机构所负责的区域

重要的Internet管理机构和常用的WHOIS服务器

机构缩写

WHOIS服务器地址

机构全名及地点

提供查询内容

CERNIC

(清华大学·中国北京)

中国教育网内的IP地址和.edu.cn域名信息

CNNIC

.cn域名(除.edu.cn)信息

INTERNIC

(美国洛杉矶市Marina del Rey镇)

.com,.net,.org,.biz,.info,.name

域名的注册信息(只给出注册代理公司)

ARIN

(美国弗吉尼亚州Chantilly市)

全世界早期网络及现在的美国、加拿大、撒哈拉沙漠以南非洲的IP地址信息

APNIC

(澳大利亚昆士兰州密尔顿镇)

东亚(包括中国大陆和台湾)、南亚、大洋洲IP地址注信息

RIPE

欧洲、北非、西亚地区的IP地址信息

TWNIC

.tw域名和部分台湾岛内IP地址信息

JPNIC

whois.nic.ad.jp

.jp域名和日本境内的IP地址信息

KRNIC

.kr域名和韩国境内的IP地址信息

LACNIC

拉丁美洲及加勒比海诸岛IP地址信息

本机上的自动WHOIS服务,是按照下图所示的流程,依次查询若干个WHOIS服务器之后,得到某个IP地址的WHOIS信息。

当我们准备建立一个Web站点,就必须向域名登记机构申请一个Internet域名,因此,我们通常希望了解自己准备使用的域名是否已经被注册,这时,可以简单地访问InterNIC站点ICANN Lookup,在”Registry Whois”输入框中输入需查询的域名,就可以得到我们需要的结果。本文介绍了如何

使用Java编程来实现这个过程。

 二、原理

原理非常简单,域名的查询主要是基于RFC 954提供的WHOIS协议。在上述过程中,我们实际上是访问了InterNIC站点的WHOIS服务器,该服务器从WHOIS数据库中查询我们所需要的内容。

WHOIS服务器是一个基于”查询/响应”的TCP事务服务器,它运行在SRI-NIC机器上(whois.internic.net),向 用户提供internet范围内的目录服务。本地主机上的用户程序可以通过Internet访问该服务器,其过程主要有下面三步:

(1)在TCP服务端口43(十进制)连接SRI-NIC服务主机;

(2)发送一个命令,以回车和换行结尾;

(3)接受相应命令的返回信息,一旦输出结束,服务器将关闭连接。

命令的格式非常简单。可以直接输入域名,例如,可以使用”sohu.com”查询”搜狐”网站的域名信息;也可以使用”help”得到详细的帮助信息。

 使用python简单实现whois查询的实例代码如下:

#coding=utf-8

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect(('whois.internic.net', 43))

s.send('sina.com.cn \r\n')

while 1:

        v = s.recv(1024)

        if v == '' or v == None:

                break

        print v

s.close()

但是上面的代码查询的内容很挫,根本不全面,原因是连接的whois服务器的原因。知道whois查询的原理就可以了,在python中进行进行whois查询不用重复造轮子,python中已经有相应的whois查询模块供使用,下面简单介绍两个模块,我推荐使用第二个whois查询模块,因为第一个是调用的linux的whois命令导致必须linux安装whois工具后才能使用且结果也不全面。

三、编程

一、python的whois模块

模块介绍地址:https://code.google.com/p/python-whois/。其官方介绍:

Python wrapper for Linux “whois” command

simple interface to access parsed WHOIS data for a given domain

able to extract data for all the popular TLDs (com, org, net, pl, …)

query a WHOIS server directly instead of going through an intermediate web service like many others do

no external dependencies

works with Python 2.4+ and Python 3.x

all dates as datetime objects

possibility to cache results

可以看到python-whois模块仅仅是linux下的whois命令的封装,要使用该模块必须先要安装whois工具。

1

sudo apt-get install whois

安装完whois后,就可以方便的使用whois命令查看域名的whois信息,如whois jinglingshu.org

可以看到安装好whois工具后,可以很容易的使用whois命令进行whois信息查询。因此,我们在python中进行whois信息查询的另外一条死路是通过python调用whois命令进行查询,然后对结果进行分析处理。python-whois的模块的思路就是这样的,不过不知为啥python-whois获取的whois信息并不如whois命令获取的信息那么完整,这也是我最终弃用python-whois模块的原因。

python-whois模块的使用例子:

>>> import whois

>>> domain = whois.query('google.com')

>>> print(domain.__dict__)

{'expiration_date': datetime.datetime(2020, 9, 14, 0, 0), 'last_updated': datetime.datetime(2011, 7, 20, 0, 0), 'registrar': 'MARKMONITOR INC.', 'name': 'google.com', 'creation_date': datetime.datetime(1997, 9, 15, 0, 0)}


>>> print(domain.name)

google.com

>>> print(domain.expiration_date)

2020-09-14 00:00:00

 二、pywhois模块

模块的详细介绍地址:https://code.google.com/p/pywhois/。该模块使用方便,而且获取的信息非常完整,因此在实际使用时建议使用此模块。

模块介绍:

Create a simple importable Python module which will produce parsed WHOIS data for a given domain.

Able to extract data for all the popular TLDs (com, org, net, …)

Query a WHOIS server directly instead of going through an intermediate web service like many others do.

Works with Python 2.4+ and no external dependencies

安装命令:

1

pip install python-whois

即可以通过pip进行简便的安装,至于linux如何安装pip工具可以翻阅以前写的文章。pywhois模块的示例代码:

>>> import whois

>>> w = whois.whois('webscraping.com')

>>> w.expiration_date  # dates converted to datetime object

datetime.datetime(2013, 6, 26, 0, 0)

>>> w.text  # the content downloaded from whois server

u'\nWhois Server Version 2.0\n\nDomain names in the .com and .net

...'

>>> print w  # print values of all found attributes

creation_date: 2004-06-26 00:00:00

domain_name: [u'WEBSCRAPING.COM', u'WEBSCRAPING.COM']

emails: [u'WEBSCRAPING.COM@domainsbyproxy.com', u'WEBSCRAPING.COM@domainsbyproxy.com']

expiration_date: 2013-06-26 00:00:00

可以看到pywhois模块使用非常方便,获取的信息也非常完整。不过由于和上一个模块一样同样是import whois,所以两个可能有冲突,在安装pywhois模块时如果以前安装过一中介绍的python-whois最好先要将其卸载掉,其卸载命令:sudo easy_install -m whois。

在实际使用时,使用whois.whois()函数就可以获取域名的whois信息,获取的属性中比较重要的有emails、name_servers、registrar、whois_server属性,要获取全部内容可以使用text属性

ps:不仅可以进行域名whois查询,有些网站同时提供了whois域名反查的功能(whois反查功能可以通过注册人或者注册人邮箱反查whois信息,得到相同信息的其它域名列表。通过whois反查,可以了解到域名所有者拥有哪些域名)。现在提供whois反查的网站有:

三、Golang实现:

package main

import (
	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
	"net"
	"os"
)

const server = "whois.internic.net"

/**
whois 查询
*/
func query(domain string) (string, error) {
	conn, err := net.Dial("tcp", server+":43")
	if err != nil {
		return "", err
	}
	defer conn.Close()

	conn.Write([]byte(domain + "\r\n"))

	var buffer = make([]byte, 2048)

	n, err := conn.Read(buffer)

	if err != nil {
		return "", err
	}

	return string(buffer[:n]), nil
}

/**
golang实现的whois查询小工具
*/
func main() {
	os.Setenv("FYNE_THEME", "light")
	a := app.New()
	w := a.NewWindow("whois tools v1.0")

	w.Resize(fyne.NewSize(600, 350))
	w.CenterOnScreen()
	domainEntry := widget.NewEntry()
	resultEntry := widget.NewMultiLineEntry()
	queryButton := widget.NewButton("query", func() {
		result, err := query(domainEntry.Text)
		if err != nil {
			resultEntry.SetText("ERROR: " + err.Error())
		} else {
			resultEntry.SetText("")
			resultEntry.SetText(result)
		}
	})

	w.SetFixedSize(false)
	w.SetContent(widget.NewVBox(
		domainEntry,
		queryButton,
		resultEntry,
	))

	w.ShowAndRun()
}