Image
WARCannon 旨在简化和降低“搜索互联网”这一过程的成本与复杂度。
通过 WARCannon,你可以:
WARCannon 巧妙利用 AWS 技术实现水平扩展至任意规模,通过竞价实例集群和同区域数据传输降低成本,以惊人速度(每节点高达 100Gbps)从 S3 拉取数据,跨数百个 CPU 核心并行处理,通过 DynamoDB 和 CloudFront 报告状态,并通过 S3 存储结果。
总体而言,WARCannon 可以在几小时内,以大约 30 美元的成本处理 400TB 数据中的多个正则表达式模式。
最快、最简单的上手方式是使用 AWS CloudShell。只需粘贴以下单行命令:
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/master/cloudshell/deploy.sh)
如果你想使用 WARCannon 的非 master 分支,只需输入:
export GIT_BRANCH=branch_name
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/$GIT_BRANCH/cloudshell/deploy.sh)
注意:CloudShell 部署使用临时存储,这意味着当 CloudShell 退出时,自定义正则表达式模式会丢失。如果你要频繁使用 WARCannon,建议使用下面的“本地安装”。
WARCannon 要求你已安装以下软件:
专业提示: 为了让 WARCannon 与 AWS 中你可能已有的其他内容保持干净和区分,强烈建议在全新的账户中部署 WARCannon。你可以通过 AWS 的“组织”控制台轻松创建新账户。所谓的“强烈建议”,其实就是“千万不要把它装在其他东西旁边”。
首先,克隆仓库并复制示例设置文件。
$ git clone [email protected]:c6fc/warcannon.git
$ cd warcannon
warcannon$ cp settings.json.sample settings.json
根据需求编辑 settings.json:
必需设置
nodeInstanceType:一个实例类型数组,用于并行处理。'c' 类型在此场景下性价比最高,任何大小均可。对于真正的活动,推荐值为 ["c5n.18xlarge"]。nodeCapacity:在并行处理期间请求的节点数量。产生的节点将是你指定的 nodeInstanceTypes 的任意分布。nodeParallelism:每 vCPU 同时处理的 WARC 数量。2 是一个不错的值。如果节点在此并行度下 RAM 不足(例如在使用 'c' 类型实例时可能会遇到),它们将以最高安全并行度运行。nodeMaxDuration:计算节点的最大生命周期(秒)。如果作业在此时间后仍未完成,节点将被自动终止。默认值为 24 小时。可选设置(如果不用,则完全省略它们)
sshKeyName:已在 us-east-1 中存在的 EC2 SSH 密钥名称。allowSSHFrom:允许 SSH 访问的 CIDR 掩码。通常会是 <你的公网IP>/32。要安装,运行以下命令:
$ npm install
$ npm link
$ warcannon deploy
在 WARCannon 中运行一次活动使用一个简单易懂的工作流程,可以用以下几个步骤来概括:
warcannon deploywarcannon testLocal -swarcannon testwarcannon list 2022warcannon populate 2022-21warcannon firewarcannon syncResults 从 S3 检索结果。继续阅读每个步骤的更详细理解。
WARCannon 通过 AWS 开放数据 计划由 Common Crawl 提供数据。Common Crawl 的独特之处在于,其爬虫检索的数据不仅包含网站文本,还包含其他基于文本的内容,如 JavaScript、TypeScript、完整 HTML、CSS 等。通过构建能够识别独特组件的合适正则表达式,研究人员可以根据网站使用的技术来识别网站,而无需实际接触网站本身。问题在于,这需要解析数百 TB 的数据,无论你拥有多少资源都是一项艰巨任务。幸运的是,WARCannon 提供了多种工具来帮助你完成这项任务!
搜索互联网并非易事,但使用一个有效的筛选器是第一步。WARCannon 支持通过本地验证正则表达式与真实的 Common Crawl 数据来实现这一点。首先,打开 lambda_functions/warcannon/matches.js 并修改 regex_patterns 对象,以 name: pattern 格式包含你希望使用的正则表达式。以下是默认搜索集的示例:
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
匹配此表达式的字符串将按照结果中对应的键保存;在本例中为 access_key_id。专业提示: 使用 RegExr 并选择 'JavaScript' 格式,针对已知匹配项构建和测试正则表达式。
你还可以选择仅从指定域捕获结果。为此,只需将 FQDN 填充到 domains 数组中即可。建议将其留空 [],因为几乎不值得这样做(节省的处理工作量很小),但在某些小众情况下可能有用。
exports.domains = ["example1.com", "example2.com"];
一旦 matches.js 填充完毕,运行以下命令:
warcannon$ warcannon testLocal -s
你可以选择性地在 commoncrawl S3 存储桶中添加一个 WARC 的路径,否则将使用硬编码的默认值。
WARCannon 将流式处理 WARC 文件(如果省略 -s 则会完全下载)以查找你配置的匹配项。当你用 ctrl+c 中断或处理完成时,WARCannon 会将结果保存到 ~/.warcannon/ 文件夹中。这使得可以以最小带宽快速测试常见匹配项。
除此之外,WARCannon 还会在本地运行时尝试评估正则表达式的总计算成本。这样,你可以在执行活动之前了解某个正则表达式是否会显著影响性能。

有时,简单的正则表达式模式不足以满足需求,你需要额外的步骤来确保返回正确的信息。在这种情况下,只需在 exports.custom_functions 对象中添加一个与相同键名对应的函数,即可执行任何你认为合适的额外处理。
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
exports.custom_functions = {
"access_key_id": function(match) {
// 忽略包含 'EXAMPLE' 的匹配项,这在文档中很常见。
if (match.text(/EXAMPLE/) != null) {
// 返回布尔值 'false' 则丢弃该匹配项。
return false
}
}
}
注意:WARCannon 旨在以极快的速度处理文本。 虽然你当然可以执行任何类型的操作,但添加高延迟的自定义函数(如网络调用)会显著增加处理时间和成本。网络调用也可能导致对某个网站的大量请求,从而给你带来麻烦。请明智地使用这些函数。
AWS 的成本可能会引起焦虑,尤其是当你只想做一些研究时。WARCannon 除了支持完整活动外,还支持一次性执行,因此你可以对返回的结果充满信心。当你对 testLocal 的结果满意后,可以部署更新后的匹配项并轻松运行云支持测试:
warcannon$ warcannon deploy
warcannon$ warcannon test
同样,你可以选择性地包含一个 WARC Path,但不是必须的。
这将同步执行一个 Lambda 函数,使用你配置的正则表达式,并立即返回结果。此过程大约需要 2.5 分钟,所以不用担心等待其完成魔法。
一旦你对 Lambda 中的结果满意,就可以真正地搜索互联网了。我们首先介绍一些基本的维护工作,然后启动它。
WARCannon 使用 AWS 简单队列服务将工作分发给计算节点。为了确保你的结果不受先前运行的影响,你可以让 WARCannon 清空队列:
warcannon$ warcannon emptyQueue
[+] Cleared [ 15 ] messages from the queue
然后你可以验证队列的状态:
warcannon$ warcannon status
Deployed: [ YES ]; SQS Status: [ EMPTY ]
Job Status: [ INACTIVE ]
Active job url: https://d201offlnmhkmd.cloudfront.net
在继续之前,请确认以下事项:
为了创建计算节点将要消费的队列消息,你必须先用爬取数据填充 SQS。WARCannon 有几个命令可以帮助实现这一点,首先是显示可用扫描的功能。在这种情况下,我们查看 2021 年可用的扫描:
warcannon$ warcannon list 2021
CC-MAIN-2021-04
CC-MAIN-2021-10
我们有两个匹配字符串 "2021" 的扫描可以处理。现在,我们可以指示 WARCannon 基于其中一个扫描填充队列。这一次,我们需要提供一个唯一标识其中一个扫描的参数。"2021-04" 就能满足要求。我们也可以选择只填充部分扫描,通过指定块的数量和大小,但我们现在先跳过这个。
warcannon$ warcannon populate 2021-04
{Created 799 chunks of 100 from 79840 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
在部署过程中,WARCannon 会自动在 Athena 中配置一个数据库(warcannon_commoncrawl)和一个工作组(warcannon),可用于快速查询 CommonCrawl 的信息。这对于基于某些查询填充稀疏活动特别有用。例如,以下查询将搜索包含来自 'example.com' 响应的 WARC:
SELECT
warc_filename,
COUNT(url_path) as num
FROM
warcannon_commoncrawl.ccindex
WHERE
subset = 'warc' AND
url_host_registered_domain IN ('example.com') AND
crawl = 'CC-MAIN-2021-04'
GROUP BY warc_filename
ORDER BY num DESC
你可以使用 Athena 控制台微调你的结果,但如果你打算用它来填充作业,则必须从 WARCannon 命令行运行查询:
warcannon queryAthena "SELECT warc_filename, COUNT(url_path) as num FROM warcannon_commoncrawl.ccindex WHERE subset = 'warc' AND url_host_registered_domain IN ('example.com') AND crawl = 'CC-MAIN-2021-04' GROUP BY warc_filename ORDER BY num DESC"
[+] Query Exec Id: 0319486e-1846-491c-badf-2e23ae213974 .. SUCCEEDED
然后,WARCannon 可以使用查询结果来填充队列,并基于结果集中的 warc_filename 列进行填充。因此,建议你 group by 此列或使用 distinct() 来避免重复。如果此字段不存在,WARCannon 将抛出错误。通过将查询执行 ID 传递给 populateAthena 命令,使用 Athena 结果填充队列。
warcannon populateAthena 0319486e-1846-491c-badf-2e23ae213974
{Created 26 chunks of 10 from 251 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
注意:虽然为单个域填充稀疏作业似乎是个好主意,但通常并非如此。 单个域的响应往往广泛分布在大量的 WARC 中。使用上面的示例查询可以清楚地看到这一点:在每个 WARC 约 150,000 条记录中,中等规模网站的最大单次命中次数可能只有个位数。
队列已填充,我们准备开火。WARCannon 会进行一些完整性检查以确保一切正常,然后显示活动的配置,并在你最终确定命令之前给你最后一次中止的机会。
warcannon$ warcannon fire
[!] This will request [ 6 ] spot instances of type [ m5n.24xlarge, m5dn.24xlarge ]
lasting for [ 86400 ] seconds.
To change this, edit your settings in settings.json and run warcannon deploy
--> Ready to fire? [Yes]:
通过输入 'Yes' 来触发。
--> Ready to fire? [Yes]: Yes
{
"SpotFleetRequestId": "sfr-03dd32b8-51f7-4c8e-802b-a702fc3c8c95"
}
[+] Spot fleet request has been sent, and nodes should start coming online within ~5 minutes.
Monitor node status and progress at https://d201offlnmhkmd.cloudfront.net
响应中包含一个指向你唯一状态 URL 的链接,你可以在其中监视活动的进展以及每个节点的性能。

WARCannon 的结果以 JSON 格式存储在 S3 中,按每个负责生成结果的节点进行细分。Athena 结果存储在同一个存储桶的 /athena/ 前缀下。你可以使用 syncResults 命令将活动的结果同步到本地机器上的 ~/.warcannon/ 文件夹。
warcannon syncResults
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
...
然后你可以使用 clearResults 清空结果存储桶。
warcannon clearResults
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
...
[+] Deleted [ 21 ] files from S3.
有问题需要帮助,想贡献代码,或者想炫耀胜利?欢迎加入 Discord!