跳转到主要内容

Net::Whois - 爬虫工具通过 RDAP 和 WHOIS 检查域名数据

爬虫工具概览

爬虫工具概览

域名数据通过 RDAP (HTTP, JSON)、WHOIS (43 端口) 或运营商的网页进行采集,具体取决于域名后缀。爬虫工具为每个 TLD 预设了 RDAP 和 WHOIS 服务器;如果该后缀支持 RDAP,则优先通过其执行请求,出错时转至 WHOIS;若两者皆无,则在有网页查询入口的情况下通过网页采集。

校验方式的组合取决于运营商,而不止是 TLD。部分后缀没有 WHOIS 或 RDAP,或者它们无法工作——这是由运营商决定的。并非所有后缀都有查询网页:其是否存在也由运营商设定。如果存在网页,爬虫工具将通过它请求数据。

在某些后缀中,运营商仅拥有 TLD,而网站注册在 SLD(二级域名,例如 co.ukorg.uk)上。SLD 的所有者可能是一个或多个,但并非 TLD 运营商。校验方式的组合由 SLD 所有者设定:WHOIS、RDAP、网页、它们的组合,或者什么都没有。

受法律、运营商政策和个人数据限制的影响,WHOIS 和 RDAP 中的字段组成也可能有所不同。但总体字段集是可预测的:注册信息、日期、NS、注册商、状态。

通过网页采集时没有统一标准。系统始终会检查域名是否已注册。其余信息取决于运营商在页面上展示的内容:可能是几乎完整的数据集,也可能仅包含已注册这一事实。

详情请参阅:RDAP (英文),WHOIS

A-Parser 的功能允许保存数据抓取设置以供后续使用(预设),设置数据抓取计划等等。您可以使用查询自动扩展、从文件替换子查询、遍历数字字母组合及列表,以获取尽可能多的结果。

由于内置了强大的 Template Toolkit 模板引擎,您可以按所需的任何形式和结构保存结果,该引擎允许对结果应用额外的逻辑,并以各种格式输出数据,包括 JSON, SQL 和 CSV

爬虫工具应用案例

采集的数据

以下列表是 WHOIS/RDAP 的典型数据集;具体字段取决于服务器响应和法律规定。通过 Web 方式采集时,仅能保证确认域名是否已注册;其他字段仅在运营商公开时填充。

  • $registered — 域名是否已注册
  • $expire_date — 域名注册到期日期
  • $creation_date — 域名注册日期
  • $free_date — 域名释放日期
  • $whoisserver — 使用的 WHOIS 服务器(进行 WHOIS 查询时;RDAP 查询时通常为空)
  • $rdapserver — RDAP 服务器 URL(RDAP 查询成功时)
  • $registrar — 域名注册商
  • $updated_date — 记录最后更新日期
  • $data — 原始响应:WHOIS 文本或 RDAP JSON
  • 数组 $ns (Name servers):
    • $ns.$i.server — NS 服务器名称
  • 数组 $statuses (Statuses list):
    • $statuses.$i.status — 域名状态

功能

  • 根据域名后缀自动选择 RDAP 或 WHOIS(RDAP 优先)
  • 如果该后缀没有可用的 WHOIS/RDAP,但有运营商网页,则通过网页进行检查
  • WHOIS/RDAP 字段的组成取决于服务器响应和法律法规
  • 通过 Web 方式采集时始终检查域名是否存在;其他字段仅在运营商提供时获取
  • 部分域名后缀(TLD 和 SLD)既没有 WHOIS/RDAP,也没有网页 —— WHOIS 数据不可用,但可以通过 Net::DNSNet::DNS 检查域名的存在性
  • 支持处理国际化域名(IDN,例如 яндекс.рф)

使用场景

  • 采集未注册域名或即将释放的域名
  • 采集 NS 服务器列表
  • 获取域名状态

查询

查询时需要指定目标网站的域名,例如:

a-parser.com  
yandex.ru
google.com
vk.com
facebook.com

结果输出选项

得益于内置的 Template Toolkit 模板引擎,A-Parser 支持灵活的结果格式化,允许以任意形式以及结构化形式(如 CSV 或 JSON)输出结果。

默认输出

结果格式:

$query - registered: $registered, expire: $expire_date, creation: $creation_date

结果显示了域名、是否已注册、到期日期和注册日期:

facebook.com - registered: 1, expire: 30.03.2028, creation: 29.03.1997
a-parser.com - registered: 1, expire: 25.02.2022, creation: 25.02.2012
vk.com - registered: 1, expire: 23.06.2021, creation: 24.06.1997
yandex.ru - registered: 1, expire: 01.10.2021, creation: 23.09.1997
google.com - registered: 1, expire: 14.09.2028, creation: 15.09.1997

输出 NS 列表

结果格式:

$ns.format('$server\n')

结果示例:

demi.ns.cloudflare.com
vern.ns.cloudflare.com

将域名期限数据输出到 CSV

结果格式:

[% tools.CSVline(query, registered, expire_date, creation_date, updated_date, free_date, whoisserver, rdapserver, registrar) %]

结果示例(.com 域名,通过 RDAP 响应 — whoisserver 为空,rdapserver 已填充):

a-parser.com,1,25.02.2027,25.02.2012,10.02.2026,none,,https://rdap.verisign.com/com/v1/domain/a-parser.com,"Squarespace Domains II LLC"

将 NS 列表输出到 CSV 表格

结果格式:

[% FOREACH ns;
tools.CSVline(query, server);
END %]

结果示例:

a-parser.com,demi.ns.cloudflare.com
a-parser.com,vern.ns.cloudflare.com

将结果转储为 JSON

通用结果格式:

[% IF notFirst;
",\n";
ELSE;
notFirst = 1;
END;

obj = {};
obj.query = query;
obj.registered = p1.registered;
obj.expire_date = p1.expire_date;
obj.creation_date = p1.creation_date;
obj.updated_date = p1.updated_date;
obj.free_date = p1.free_date;
obj.whoisserver = p1.whoisserver;
obj.rdapserver = p1.rdapserver;
obj.registrar = p1.registrar;
obj.domains = [];

FOREACH item IN p1.ns;
obj.domains.push({
server = item.server
});
END;

obj.json %]

起始文本:

[

结束文本:

]

结果示例 (RDAP):

[{
"registered": 1,
"rdapserver":"https://rdap.verisign.com/com/v1/domain/a-parser.com",
"query":"a-parser.com",
"free_date":"none",
"domains":[
{
"server":"demi.ns.cloudflare.com"
},
{
"server":"vern.ns.cloudflare.com"
}
],
"registrar":"Squarespace Domains II LLC",
"expire_date":"25.02.2027",
"creation_date":"25.02.2012",
"whoisserver":"",
"updated_date":"10.02.2026"
}]
提示

要在任务编辑器中使用“Prepend text”和“Append text”选项,需要激活“More options”。

结果处理

A-Parser 允许在数据抓取过程中直接处理结果,在本节中,我们介绍了 Net::Whois 爬虫工具最常用的案例。

获取域名注册商

通过 WHOIS 响应时,$p1.data 字段包含文本;通过 RDAP 时则包含 JSON。为了在两种情况下都能获取注册商,请添加两个结果构造器

添加Result Builders (结果构造器),在下拉列表中选择源:$p1.data。选择类型:RegEx Match。在正则表达式字段中输入:Registrar:\s*(.+) 并保存到变量 registrarwhois

再次添加Result Builders (结果构造器),在下拉列表中选择源:$p1.data。选择类型:RegEx Match。在正则表达式字段中输入:"entities"[\s\S]+?"vcardArray"[\s\S]+?"fn"[\s\S]+?"text"[\s\S]+?"([^"]+?)" 并保存到变量 registrarrdap

Result format (结果格式)中添加:[% IF registrarrdap == 'none' %]$query - $registrarwhois[% ELSE %]$query - $registrarrdap[% END %] — 如果 RDAP 未找到名称(registrarrdap 等于 none),则输出 WHOIS 的值,否则输出 RDAP 的值。

下载示例

如何将示例导入 A-Parser

eJyVVNtO20AQ/RVrFEQoJioPfbGEqkATiSpNKAH1wU6lVTxJt6x3ze46EEX5987Y
jh1TpKpP9lzPmdvuYIPWSaMhugzBC/fk7iw69A6ieAd5+Q8RWFxL562wEEIurKMg
cohhij6Kfvwy0pEhxZUolIdwB36bI4UZym5limSUKckrYzPhKWnpBhuhCnaLT4Lb
cdBg2FTkwdVVcKqNxtPgZNF7LtBug4ug1/i8MCbFjSbz0fsenIUdpl/InmjYLxYh
VNBuXPIg5F5+OaiLbIxzscEHw2ylwlY9JmkqMubbS4VHtg6qgvpnA//KGUSaSk/d
FKpC4Ca1qI9aPnO9K6EchsCUJbqxNRnl9FhmKOs40IuhqgsoR1EGf69imhyOuI4F
MUnfWqRHK7yxs5wJkX4HRg+VmuAGleuQ2F4XUqU00uGKgm7rwPddZn/l2Df1HUPR
4F8scWiylNL17FsblZqJWTd2JTPpSeFuTKGp9o8hPCHmh57B1FB3MmOxQakDa3Ba
2xw1L1k7smHeqjpVdMZypNyBM4VdEl5M+DRlwa2vl5k2C1/L5PyN4P6waVGSuA/9
wfnZwfhQBZDoDU+xu7Ww2If/BZQAak97hS6BmLCSZL44/5zAZilsOrRWbLv6le7K
vFpdTT/+mQD9nSXwT858R0SZ6C2NXsn1rL7pQxML/UDPxkzfmCxXyBPXhVK0sA7v
28sZunpBWWhn9zb4poQgHs1bQnSMcl/nFbfcSmL3iTlntGPHqHXKpVDq8X5ybOFA
500+0yNr3yx2eTIgLqpHbbCkW2wvs6TKRS7p3teGDpEk7kT9BDZP5Y7W+be7q7Qc
Vur2fwBx19yZ

可用设置

参数默认值描述
Recursive query允许获取 WHOIS 的扩展版本
WHOIS server允许指定自定义 WHOIS 服务器
RDAP server允许指定自定义 RDAP 服务器
Checking by DNS允许根据域名是否存在 IP 来检查域名是否已注册
Checking domains by DNS recordIP 检查,如果发现状态为 ALLOCATED,则判定域名已注册;如果禁用此选项,则完全不进行 IP 检查
Force DNS check for not found domains如果域名被判定为未注册,则进行强制检查