一、简介
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()
}