在构建外挂 RAG 时,Common Crawl (CC) 代表了“贪婪”的极致——它几乎就是互联网本身。它是目前地球上最大的、免费开放的网页存档,每个月新增数以亿计的页面,总数据量达到 PB(拍字节)级别。
对于 RAG 开发者而言,CC 既是宝库也是沼泽。
本章的任务是教你“戴着手套解剖”。我们将深入 CC 的底层文件协议(WARC/WAT/WET),揭示如何利用高效的索引机制(CDX/Parquet)在不下载文件的情况下透视数据,并制定一套符合经济效益的获取策略。
Common Crawl 的数据分发采用了一种标准化的分层结构。理解这种结构,是你决定“该请求哪个文件”的关键。
CC 的处理流程是一个从“全量原始数据”到“高密度文本数据”的蒸馏过程。
[ 原始互联网 (The Live Web) ]
|
v (Nutch/Browsertrix 爬虫)
|
+-----------------------------------------------------------+
| 1. WARC (Web ARChive) - "母带" |
| --------------------------------------------------------- |
| 格式:ISO 28500 标准 |
| 内容:HTTP Request + HTTP Response (Header + Body) |
| 体积:100% (压缩前极大) |
| 特征:二进制安全,包含图片、PDF、HTML 源码、服务器指纹 |
+-----------------------------------------------------------+
|
+----------------------------+
| (Java 提取程序) | (Java 提取程序)
v v
+-----------------------+ +-----------------------+
| 2. WAT (Metadata) | | 3. WET (Text Only) |
| --------------------- | | --------------------- |
| 格式:JSON-in-WARC | | 格式:纯文本-in-WARC |
| 内容:计算后的元数据 | | 内容:提取后的正文 |
| 链接图谱 | | 去标签、去脚本 |
| HTML 结构统计 | | 按视觉块分段 |
| 体积:~25% | | 体积:~15-20% |
| 用途:分类、筛选 | | 用途:RAG 核心语料 |
+-----------------------+ +-----------------------+
WARC 文件是多个 Record (记录) 的拼接。每个 Record 都有标准化的 Header。
WARC-Type: warcinfo (文件头), response (服务器响应), request (爬虫请求), metadata (爬虫元数据)。WARC-Target-URI: 抓取的原始 URL。Content-Type: application/http; msgtype=response。HTTP/1.1 200 OK、Server: Apache 等头信息,以及 <html>...</html> 正文)。<img> src) 或 PDF 文件,必须用 WARC。WAT 是从 WARC 中提取的元数据,封装在 JSON 格式中,但仍然包裹在 WARC 容器里。
Envelope: 包含 WARC 头信息。Payload-Metadata:
HTTP-Response-Metadata: 包含 Header (Content-Length, Content-Type, ETag)。HTML-Metadata: 及其重要!包含 Head (Title, Meta Keywords, OpenGraph Tags), Links (页面内所有外链的列表), Structure (HTML 标签的层级分布)。Links 数量判断是否为“链接农场”;通过 HTML-Metadata 中的文本/标签比率判断是否为有效内容页。ETag 或 Payload 的哈希值。这是 99% 的 RAG 项目应该关注的格式。 它不仅去掉了 HTML 标签,还尝试根据 DOM 结构将文本还原为人类阅读顺序。
.wetz (GZIP 压缩)。WARC/1.0 协议头分隔。<h1> 和 <p> 在视觉上可能难以区分(取决于提取器版本)。Rule of Thumb (选型法则): 默认起手 WET。 如果你的 RAG 需要处理 编程代码 (需要缩进)、科学论文 (需要公式) 或 复杂表格,请立即升级为 下载 WARC + 自研 HTML 解析器,不要试图修复 WET。
CC 提供了两种索引机制,让你在下载之前就能精准定位到具体的字节片段。
这是一个基于 HTTP 的 API,允许你按 URL 模式进行行级查询。
(URL, Timestamp) -> (File_Path, Offset, Length, Digest) 的映射。example.com/foo。*.example.com/* (所有子域名和路径)。urlkey: 规范化后的 URL(忽略 http/https,翻转域名 com,example 以便于排序)。timestamp: 抓取时间(YYYYMMDDHHMMSS)。digest: 内容指纹 (SHA-1)。这是 RAG 去重的核心字段。filename: S3 上的相对路径 (e.g., crawl-data/CC-MAIN-2023-50/...).offset / length: 文件中的位置和大小。对于复杂的分析查询,CDX 力不从心。CC 提供了存储在 S3 上的 Parquet 格式索引,支持 SQL 查询(通过 AWS Athena 或 Spark)。
.jp 结尾的、HTTP 状态码为 200 的、内容语言被标记为日文的页面列表。”text/html 的记录),生成一份目标 URL 清单,然后再去下载数据。有了索引(位置信息),下一步是获取数据。切记:不要下载整个文件。
CC 的文件(WARC/WET)虽然被压缩为 .gz,但它们是 Concatenated Gzip 格式。
Range 头。例如,索引告诉你数据在 offset=1048576, length=5000。
GET /crawl-data/.../segment.warc.gz.wetz HTTP/1.1
Host: data.commoncrawl.org
Range: bytes=1048576-1053575
你将只收到这 5KB 的压缩数据。解压后即为该网页的完整内容。
CC 数据托管在 AWS 公共数据集桶中 (s3://commoncrawl/)。
us-east-1 (N. Virginia)。Rule of Thumb (架构建议): 计算跟着数据走。
- 在 AWS
us-east-1开一台 Spot 实例(如c7g.medium)。- 在实例上运行脚本:查询索引 -> Range Download -> 解析清洗 -> 提取 Chunk。
- 只将最终清洗好的 JSONL(可能只有原大小的 1%)传回你的本地服务器或向量库。 严禁:在本地笔记本上直接遍历下载 CC 数据。
us-east-1 区域内进行,否则流量费会让你破产。digest 字段,在下载前就剔除重复内容。Q1: 格式选择
你的 RAG 系统需要专门回答关于“网页加载速度优化”的问题,你需要分析每个网页的 HTTP 响应头中的 Cache-Control 和 Server 字段,以及页面 HTML 的压缩比。你应该使用哪种 CC 文件格式?
Q2: 索引解读
CDX 索引返回一条记录,其中 status 字段为 301。这代表什么?你在构建 RAG 语料时应该如何处理这条记录?
Q3: 范围下载 为什么 Common Crawl 的 Gzip 文件可以从中间解压?这依赖于什么特性?
Q4: 增量更新设计 (开放性)
假设你已经基于 CC-MAIN-2023-50 构建了一个 RAG 知识库。现在 CC-MAIN-2024-01 发布了。请设计一个流程,将新数据合入知识库,要求:1. 不重复索引已有的网页内容;2. 能够更新那些内容发生了变化的旧网页。
Q5: 跨语言清洗 (陷阱探测)
你下载了一个标记为“中文”的 WET 文件片段,但解压后发现里面是乱码且穿插着日文片假名。可能的原因是什么?除了 CC 提供的 languages 字段,你还应该加什么检测手段?
Content-LengthContent-Length 经常是错的,或者是压缩前的大小,或者是压缩后的大小,很不统一。length 字段为准来设定 Range Request 的范围。web.archive.org (Wayback Machine) 的对应快照,而不是原始链接,以保证安全性。json.load() 读取 WET 文件。WARC/1.0 标头进行正则分割。