免责声明:我们是 Geonode,我们销售代理服务,这是文末所述爬取方法所需的资源之一。 **坦率地说,爬网应该作为最后尝试的手段,而不是第一步。**下文列出的八个来源中有五个是免费的,无需任何基础设施支持,而且通常能生成比爬网更完整的列表——因为它们包含了那些已不再被任何地方链接的页面。 如果你一开始就编写爬虫,不仅工作量会更大,覆盖范围反而更小。只有在确认免费来源存在需要填补的空白后,才应购买带宽——而这个时间点通常比大多数人预想的要晚。
为什么“所有页面”没有确切答案
有四个原因,均与结构有关。
存在孤立页面。 没有入站链接的页面无法通过爬虫访问,对搜索引擎而言也是不可见的,但该页面确实存在且可能处于在线状态。旧的着陆页、营销活动链接以及已弃用的版块都属于这一类。
**表单和身份验证后的内容无法被枚举。**搜索结果、筛选后的视图以及任何需要登录的内容,都无法通过发现机制访问。
动态 URL 可能无限多。 包含下个月链接的日历会生成无限数量的 URL。电商网站上的多维导航会引发组合爆炸。“所有页面”在某些网站上并非一个有限集合。
网站会通过遗漏来“隐瞒”信息。 网站地图仅包含所有者选择列出的内容,这通常是他们希望被索引的页面,而非实际存在的所有页面。
因此,现实的目标并非完整性,而是满足您目的的充分覆盖范围,这意味着您选择的信息来源取决于您的查询目的。
从网站地图开始
这是效率最高的第一步,却也是人们最容易忽略的一步。
网站地图协议 定义了一种用于列出网站 URL 的 XML 格式。网站地图“必须以一个开头标签 <urlset> 开头,并以一个结束标签 </urlset> 结尾”,每个条目都需要一个 <loc> 元素。可选的 <lastmod>、<changefreq> 和 <priority> 元素可以随其出现,尽管该协议指出,搜索引擎对这些元素的处理方式“可能有所不同”。
这些限制会影响您的搜索结果:单个站点地图文件上限为“50,000 个 URL,且大小不得超过 50MB(52,428,800 字节)”。 大型网站会使用站点地图索引——即一个列出其他站点地图的 <sitemapindex> 文件——该文件受相同限制,因此一个网站可能包含数十个站点地图文件。
参考链接:
https://example.com/sitemap.xml
https://example.com/sitemap_index.xml
https://example.com/sitemap.xml.gz
允许使用 Gzip 压缩,“但解压后的文件仍须符合大小限制”。
请先检查 robots.txt,因为该协议允许通过 Sitemap: 指令在此处声明站点地图:
curl -s https://example.com/robots.txt | grep -i sitemap
这三十秒是极其宝贵的。许多网站列出了若干你根本无法猜到的站点地图名称——例如分别针对产品、分类、博客文章和图片的独立站点地图。
递归地追踪索引。 站点地图索引指向其他站点地图,而这些站点地图可能又指向更多的站点地图。逐一抓取它们,提取 <loc> 字段的值,并注意:索引中的条目是站点地图文件,而 urlset 中的条目则是页面。
<lastmod>字段是另一个从这里开始的原因:它会告诉你哪些内容发生了变化,从而使重新抓取仅限于抓取少数几个已移动的页面。
解读 robots.txt 文件所透露的信息
除了站点地图指令外,robots.txt 还列出了网站所有者认为值得提及的路径。
Disallow: /admin/
Disallow: /internal/reports/
Disallow: /checkout/
Disallow: /search?
Disallow 中的每一行都指明了一个真实存在的路径。这并非入侵途径——而是明确告知你哪些内容不应被抓取;遵守这一规定既符合规范,也是区分正规爬虫与骚扰爬虫的关键。但它能揭示网站的结构,并常常列出你此前未曾知晓的版块。
请将其视为一张地图,而非目标清单。被禁止的路径应始终排除在您的抓取列表之外;但了解其存在,仍有助于您理解该网站。
搜索引擎运算符
快速、免费且不完整。
site:example.com
site:example.com inurl:/products/
site:example.com -inurl:/blog/
site:example.com filetype:pdf
它能提供什么:搜索引擎已收录的页面,这只是现有页面中的一部分。搜索结果也有上限,且仅为估计值,而非穷尽所有结果。
其真正优势在于:发现您此前未知的子域名和版块,以及查找未通过导航链接访问的文档文件。在企业网站上使用 filetype:pdf 进行搜索,通常会揭示出无人预料到的公开内容。
其局限性在于:直接抓取搜索结果违反了大多数搜索引擎的使用条款,且手动操作速度较慢。若需通过编程方式实现,请优先使用官方搜索 API(如有),而非对网页界面进行自动化操作。
网络档案
这是大多数人容易忽略的资源,也是唯一能找到已不存在的网页的资源。
互联网档案馆的 CDX 服务器 API 可直接查询该档案馆的抓取索引。 文档中指出:“对 CDX 服务器而言,最简单的查询以及唯一必需的参数是 url 参数”。
curl -s "http://web.archive.org/cdx/search/cdx?url=example.com/*&output=json&fl=original&collapse=urlkey&limit=10000"
值得了解的参数:
**matchType
** 控制范围——exact
匹配一个 URL,prefix
返回路径下的所有内容,host
覆盖单个主机名,而 domain
则覆盖一个域名及其所有子域名。 URL 中的通配符会隐式设置此范围,因此 example.com/*
属于前缀匹配。
**collapse=urlkey
** 可移除相邻的重复项,这至关重要,因为存档中包含同一 URL 的多个抓取记录。
**output=json
** 比默认的 CDX 文本格式更方便,而 gzip=false
可在客户端无法处理 gzip 编码时关闭默认的 gzip 编码。
**限制:**该 API “默认强制每条查询结果上限为 150,000 条”,可通过 limit=N
进行调整;对于规模更大的查询,文档建议使用分页 API,即 page
和 pageSize
。
其独特价值在于:它能揭示历史 URL。无论是已被删除的页面、经过重组的版块,还是已断链的营销活动着陆页。若要了解网站过往的样貌,或查找仍处于在线状态的孤立内容,没有任何其他方法能与之媲美——而且它完全不会给目标网站带来任何负载。
Common Crawl
一个附带可查询索引的大型公开爬取语料库,也是一个真正被低估的资源。
Common Crawl 会定期发布对网络大部分内容的爬取结果,并附带一个 URL 索引。通过查询该索引,您可以批量获取爬取过程中发现的某个域名的 URL,且无需访问该网站本身。
其中的权衡关系很明确。覆盖范围虽广但并不完整——这毕竟是爬取数据,存在与任何爬取相同的盲区。数据的新鲜度取决于您查询的是哪次爬取。而且,大规模查询索引是一项数据处理任务,而非单次请求。
其价值体现在:大规模研究、跨域比较,以及任何希望了解网站状况却不希望向其产生流量的场景。
爬取:作为最后手段,务必妥善执行
当免费来源存在信息缺口时,进行爬取。操作时要确保不会引发问题。
**基本循环:**获取页面,提取链接,筛选目标域名,将新链接加入队列,重复此过程直至队列清空。 原理虽简单,但细节繁多。
关键细节:
严格遵守robots.txt。 这现已成为行业标准——RFC 9309 规定按特异性而非顺序进行匹配,要求至少每日刷新该文件,并将服务器错误视为完全禁止访问。 使用经过维护的库,而不是自己编写解析器。
积极地规范化 URL。 尾部斜杠、查询参数顺序、主机名的大小写、会话标识符和跟踪参数都会产生重复内容。没有进行规范化的爬虫会访问同一个页面数百次。
限制爬取范围。 设置深度限制、页面数量限制,并针对日历和多维导航设置模式排除规则。若不进行这些限制,某些网站将导致无限爬取。
自行实施速率限制。 每秒或每两秒一次请求既礼貌又足以满足大多数任务需求。robots.txt 中的 Crawl-delay 是一项值得遵守的请求。
表明身份。 带有名称和联系 URL 的用户代理,比匿名自动化程序更不容易被封禁。
使用缓存和条件请求。 If-Modified-Since 和 If-None-Match 能将重复爬取转化为一系列低成本的 304 响应。
**何时使用代理:**当达到真正的大规模爬取时,当单个IP地址被限速时,或者当内容因地区而异时。在此之前无需使用。 数据中心带宽是此处的合理默认选择——我们的起价为 0.14 美元/GB(2026 年 9 月核查)——只有当数据中心带宽明显不足时,才值得升级到住宅带宽。
其他值得了解的来源
四个规模较小但能填补特定空白的数据源。
证书透明度日志。 每份签发的 TLS 证书都会被公开记录,且证书中会标注其主机名。通过查询某个域名的 CT 日志聚合器,可以发现该域名的子域名——包括那些听起来像是内部域名、本不该通过其他途径被发现的子域名。这是发现子域名的最佳方法,且无需与目标建立联系。
RSS 和 Atom 订阅源。 目前仍被广泛发布,它们以结构化形式列出了带有日期的内容。请检查 /feed、/rss、/atom.xml 以及页面头部中的 <link rel="alternate"> 标签。
网站自身的搜索和导航功能。 无论是 A-Z 索引、标签列表、分类页面还是 HTML 网站地图页面——许多网站都会为人类访客提供此类功能,且其内容通常比 XML 网站地图更为完整。
**前端背后的 API。**如果网站是单页应用,它会调用 API 来获取内容,而该 API 通常会提供列表端点,以结构化形式返回所有内容。请查看浏览器的“网络”标签页。在现代网站中,这始终是最快的途径,却也总是人们最后才发现的途径。
整合数据源
进行严谨枚举的实用方法,以及排序之所以重要的原因。
独立收集并合并。 将网站地图 URL、存档 URL、订阅源 URL 和抓取结果整合为一个数据集。合并前需进行规范化处理,否则同一页面会被重复计数多次。
验证页面是否有效。 存档 URL 今天可能返回 404 错误。针对每个 URL 发送一次 HEAD
请求成本很低:
while read -r url; do
code=$(curl -sIL -o /dev/null --max-time 10 -w '%{response_code}' "$url")
echo "$code $url"
done < urls.txt
相互比对数据源。 仅出现在存档中但未出现在网站地图中的 URL 属于已被移除或孤立的页面;出现在网站地图中但返回 404 错误的 URL 则是过时的条目。 通过爬取发现但未出现在网站地图中的 URL,是网站所有者不希望被索引的页面。每处差异都蕴含着信息。
进行长期追踪。 定期重新运行并进行差异比对,可以告诉你哪些内容被添加了、哪些被移除了——这往往正是“查找所有页面”背后真正的问题所在。
实用操作指南
将所有来源整合到一个域名下,并按工作量最小的顺序进行。
第一步——查找已声明的站点地图:
DOMAIN="example.com"
curl -s "https://$DOMAIN/robots.txt" | grep -i '^sitemap:' | awk '{print $2}' > sitemaps.txt
# fall back to the conventional locations if nothing is declared
[ -s sitemaps.txt ] || printf 'https://%s/sitemap.xml\nhttps://%s/sitemap_index.xml\n' "$DOMAIN" "$DOMAIN" > sitemaps.txt
第二步——展开索引并收集 URL。 站点地图索引包含指向其他站点地图的 <loc>
值,而 URL 集合包含指向页面的 <loc>
值,因此相同的提取方法在两个层级上都适用,只需重复该过程即可:
extract() { curl -s --compressed "$1" | grep -o '<loc>[^<]*</loc>' | sed 's/<[^>]*>//g'; }
: > all_urls.txt
while read -r sm; do
extract "$sm" | while read -r u; do
case "$u" in
*.xml|*.xml.gz) extract "$u" >> all_urls.txt ;;
*) echo "$u" >> all_urls.txt ;;
esac
done
done < sitemaps.txt
sort -u all_urls.txt -o all_urls.txt
wc -l all_urls.txt
第三步 — 添加归档视图:
curl -s "http://web.archive.org/cdx/search/cdx?url=${DOMAIN}/*&output=text&fl=original&collapse=urlkey&limit=50000" \
| sort -u > archive_urls.txt
wc -l archive_urls.txt
第四步 — 进行比较而非简单合并。 这里生成了有趣的输出结果:
comm -13 all_urls.txt archive_urls.txt > only_in_archive.txt # orphaned or removed
comm -23 all_urls.txt archive_urls.txt > only_in_sitemap.txt # new or never archived
only_in_archive.txt
是值得首先查看的列表。这些是网站曾经提供过但不再宣传的 URL——其中一些会返回 404 错误,而那些未返回 404 的则是无人链接的在线页面。
五 — 在信任任何内容之前,先检查其是否有效。 这两个列表都包含过期的条目,而针对每个 URL 发送一次 HEAD
请求只需消耗几百字节,而非加载整页:
while read -r u; do
printf '%s %s\n' "$(curl -sIL -o /dev/null --max-time 10 -w '%{response_code}' "$u")" "$u"
done < only_in_archive.txt | tee liveness.txt
grep '^200 ' liveness.txt | wc -l
请注意这种刻意安排的顺序:参考了四个来源,收集了数千个 URL,却未编写任何爬虫程序。对于大多数网站而言,这种方法能在极短的时间内提供比爬虫更完整的全貌,且目标网站几乎察觉不到你的存在。
大家还问
如何查找网站上的所有页面?
首先访问 robots.txt 查找网站地图声明,然后获取网站地图并追踪其中的索引文件。此外,还可以借助互联网档案馆的 CDX API 查询历史 URL、RSS 源,并使用 site: 进行搜索。 仅对上述方法遗漏的内容进行抓取——这是速度最慢且侵入性最强的方式。
网站的站点地图在哪里?
通常位于 /sitemap.xml 或 /sitemap_index.xml,而最可靠的方法是通过 robots.txt 中的 Sitemap: 指令查找。大型网站通常会使用指向多个文件的站点地图索引,因为每个文件限制为 50,000 个 URL 和 50MB。
我能找到没有任何链接指向的页面吗?
有时可以。从定义上讲,爬虫无法找到这些页面,但网络档案库通常可以——互联网档案馆(Internet Archive)的 CDX API 会返回历史 URL,其中包括那些已不再被链接的 URL。证书透明度日志也会揭示那些未被任何地方链接的子域名。
如何查找一个网站的所有子域名?
证书透明度日志是最佳来源,因为每份签发的 TLS 证书都会与其主机名一起被公开记录。搜索引擎操作员和 DNS 枚举工具可作为补充。这些方法均无需联系目标网站。
爬取网站以列出其页面是否合法?
这取决于管辖权、网站的使用条款以及您对结果的处理方式。遵守 robots.txt 中的规定、标识您的爬虫并保持适度的爬取速率,即可符合常规做法。无论如何,服务条款可能禁止自动化访问,这属于合同事项,值得核查。
网站地图中可以包含多少个 URL?
每个文件最多 50,000 个 URL,未压缩大小上限为 50MB。超过此限制时,网站会使用站点地图索引文件来列出多个站点地图文件——而该索引文件本身也受同样的 50,000 个 URL 和 50MB 限制。
什么是 Wayback CDX API?
这是互联网档案馆(Internet Archive)捕获索引的一个接口,用于返回该机构为某个域名存档的 URL。matchType 可控制查询范围,从单个 URL 到整个域名及其所有子域名;collapse=urlkey 可移除重复的存档;默认结果上限为 150,000 条,对于更大规模的查询,还提供分页 API。
枚举网站页面是否需要代理?
对于网站地图、存档、RSS 源或搜索等方法,则无需代理——这些方法均不会产生显著的网络负载。仅在进行大规模爬取时才需要代理,例如单个地址受到速率限制,或内容因地区而异的情况。在购买任何服务之前,请先确认免费资源是否存在缺口。
总结
并不存在一个网站页面的完整列表,只有部分视图的并集——而有用的方法是,先收集成本较低的视图,再构建成本较高的视图。
在 robots.txt 上花三十秒就能找到站点地图声明。花几分钟追踪站点地图索引,就能了解网站所有者眼中的网站全貌。互联网档案馆的 CDX API 则补充了曾经存在但现已消失的页面,以及那些已无人链接的页面。RSS 源、证书透明度日志以及网站自身的 HTML 索引,各自填补了不同的空白。 所有这些资源都是免费的,且不会给目标网站带来任何负载。
在遵守robots.txt规则、规范化URL、限定爬取范围并保持适度爬取速率的前提下,爬取剩余内容——并首先确认该网站是否为调用API的单页应用,因为这种方式通常比爬取更快,且几乎总是被忽视。
随后,请对源数据进行比较,而非简单地合并它们。那些存在于存档中但未出现在网站地图中的页面,以及网站地图中目前返回 404 状态码的条目,往往是整个过程中最值得关注的部分。
