跳至正文
网络安全

已验证爬虫 IP 列表:用 19 份官方文件构建良性 bot 白名单

基于 10 家运营方的 19 份官方文件整理的已验证爬虫 IP 列表:文件日期、前缀数量、白名单代码,以及一个已验证却仍被评为 review 的 bot。

作者GeoIPHub 团队发布于阅读时长阅读约 29 分钟
三个玻璃服务器节点发出光束,穿过一道蓝色玻璃闸门,落在玻璃面板上对应的条带上;第四个节点发出红光,被一道小屏障拦下,象征将爬虫地址与运营方发布的 IP 段文件进行比对

一条拦截托管网络流量的防火墙规则,也会误伤您想要的爬虫。我们在 2026 年 10 月 29 日查询的每个已验证爬虫地址都位于托管网络上:ClaudeBot 在 Amazon,DuckDuckGo 在 Microsoft,AhrefsBot 在 OVH,Googlebot 在 Google 自己的网络上。如果改为按 User-Agent 放宽规则,那么每个在请求头里写上“Googlebot”的抓取程序都能长驱直入。

运营方免费公开了证明,但分散在 10 个不同网站的 19 份文件中,日期各不相同,也没有说明更新周期。其中两份文件是同一份列表。这类流量是真实存在的。Thales 在发布 Imperva 2026 年恶意 bot 报告时写道:“Bots now dominate the internet, accounting for over 53% of all web traffic, with 40% classified as malicious.”(bot 如今主导着互联网,占全部网络流量的 53% 以上,其中 40% 被归类为恶意流量。)

下文列出了每份文件在 2026 年 10 月 29 日所载的日期、GeoIPHub 的 IP 查询 API 对其中真实地址的返回结果、一个构建白名单的脚本、一个不会在共享文件上误判的策略检查,以及没有任何文件覆盖的 bot。

一个蓝色玻璃标签通过一道细光束连接到磨砂玻璃文件盒中最前面的卡片,象征将 bot 声称的名称与其运营方自己的文件进行比对
名称只是声明,运营方的文件才是证明。

良性 bot 与恶意 bot:区别在于证明,而非名称

良性 bot 是您决定放行、并且能够证明其 IP 属于其运营方的 bot。恶意 bot 至少有一项不满足,而最常见的一类,就是冒用良性 bot User-Agent 的抓取程序。

良性 bot 包括搜索爬虫、AI 搜索和用户触发的抓取器、SEO 工具以及网页存档程序。恶意 bot 包括抓取程序、撞库工具、点击 bot 和垃圾信息 bot。许多术语表说良性 bot 会“表明自己的身份”。恶意 bot 也会这么做:它们复制别人的身份,这正是抓取程序借用爬虫名称的原因。

因此,有用的问题不是“这是良性 bot 吗?”,而是“这个请求真的来自它所声称的运营方吗?”第二个问题有一个机械式的答案,这也是基于 IP 的 bot 检测的核心:运营方控制着自己的 IP 段,其他人无法控制。至于是否放行一个已被证明身份的 bot,则取决于您的策略,而且每个网站可以不同。

已验证爬虫 IP 列表:10 家运营方的 19 份官方文件

它既可以用作搜索引擎爬虫 IP 列表,用途也不止于此:GeoIPHub 加载的 19 份 IP 段文件来自 10 家运营方,从搜索引擎、AI 公司到一个存档项目和一个 SEO 工具。下表列出了每份文件的前缀数量以及文件内写明的日期,抓取时间为 2026 年 10 月 29 日 UTC 04:41 至 04:42。全部 19 份文件都返回了 HTTP 200,并且结构相同:一个由 ipv4Prefix 或 ipv6Prefix 条目组成的 prefixes 数组。

运营方Bot(文件)文件 URL前缀数(IPv4 / IPv6)文件内日期API crawler.name
Google常用爬虫,含 Googlebotcommon-crawlers.json170 / 1472026 年 10 月 28 日Googlebot
Google特殊用途爬虫,含 AdsBotspecial-crawlers.json136 / 1362026 年 10 月 28 日GoogleSpecialCrawler
Google用户触发的抓取器user-triggered-fetchers.json534 / 5342026 年 10 月 28 日GoogleUserTriggeredFetcher
Google用户触发的抓取器(google.com)user-triggered-fetchers-google.json252 / 2522026 年 10 月 28 日GoogleUserTriggeredFetcherGoogle
Google用户触发的代理程序(Google-Agent)user-triggered-agents.json12 / 82026 年 10 月 28 日GoogleUserTriggeredAgent
MicrosoftBingbotbingbot.json28 / 02024 年 1 月 3 日Bingbot
AppleApplebotapplebot.json24 / 02026 年 9 月 15 日Applebot
DuckDuckGoDuckDuckBotduckduckbot.json486 / 02026 年 9 月 1 日DuckAssistBot(见下文)
DuckDuckGoDuckAssistBotduckassistbot.json486 / 02026 年 9 月 1 日DuckAssistBot
OpenAIGPTBotgptbot.json18 / 02026 年 9 月 22 日GPTBot
OpenAIChatGPT-Userchatgpt-user.json235 / 02026 年 10 月 27 日ChatGPTUser
OpenAIOAI-SearchBotsearchbot.json39 / 02026 年 1 月 2 日OAISearchBot
AnthropicClaudeBot、Claude-User、Claude-SearchBotbots.json14 / 02026 年 10 月 20 日ClaudeBot
PerplexityPerplexity-Userperplexity-user.json10 / 02026 年 10 月 28 日PerplexityUser
PerplexityPerplexityBotperplexitybot.json13 / 02026 年 10 月 28 日PerplexityBot
MistralMistralAI-Usermistralai-user-ips.json4 / 02025 年 2 月 19 日MistralAIUser
MistralMistralAI-Indexmistralai-index-ips.json2 / 02026 年 4 月 19 日MistralAIIndex
Common CrawlCCBotccbot.json4 / 12026 年 8 月 11 日CCBot
AhrefsAhrefsBotcrawler-ip-ranges81 / 0文件内无日期AhrefsBot

GeoIPHub 的扫描器每天重新抓取所有文件。2026 年 10 月 27 日,我们从每份文件中各取一个地址进行查询,19 个地址全部返回已验证;Perplexity 的两个地址取自它在 10 月 28 日替换掉的旧文件。

总计 3,626 个前缀,其中 Google 的五份文件就占了 2,181 个。而且实际上只有 18 份不同的列表:我们抓取时,DuckDuckGo 的两份文件逐字节完全相同(MD5 哈希一致)。Perplexity 的两份文件在 10 月 27 日到 28 日之间发生了变化,前缀数从 4 和 8 变为 10 和 13。这足以提醒您:不要把任何人的表格(包括这一张)手工复制到配置文件里。

四点说明。Google 的旧路径 developers.google.com/search/apis/ipranges/googlebot.json 现在会返回 301 重定向到 common-crawlers.json,因此只要您的代码会跟随重定向,引用旧路径的老指南依然可用。Microsoft 的文件日期是 2024 年 1 月。Perplexity 的文档仍链接到 www.perplexity.com 的 URL,这些 URL 会重定向到上表中 www.perplexity.ai 的文件。另外,www.gstatic.com/ipranges/goog.json 覆盖的是 Google 的全部地址,因此它不是爬虫列表。关于 Google 的五份文件如何对应其各个爬虫组,请参阅我们的 Googlebot 指南。

匹配时返回什么:四次真实查询

在 GeoIPHub 的 API 中,匹配成功会返回 threat.crawler.verified: true、运营方、文件标签以及 verification_method: "ip_range_list"。不在任何文件中的地址会返回 verified: false,其含义仅仅是“未验证”,别无其他。以下是 ClaudeBot 的地址,摘自实时响应(2026 年 10 月 29 日 UTC 04:42:21):

GeoIPHub API
{ "asn": { "asn": 16509, "org": "AMAZON-02 - Amazon.com, Inc." }, "threat": { "is_crawler": true, "crawler": { "verified": true, "name": "ClaudeBot", "operator": "Anthropic", "category": "ai", "verification_method": "ip_range_list" } }, "scoring": { "fraud_score": 0, "recommended_action": "allow", "detection_methods": ["datacenter_ip", "no_ptr_datacenter", "verified_crawler"] } }

2026 年 10 月 29 日,dig -x 216.73.216.10 没有返回 PTR 记录,因此反向 DNS 无法为这个地址作证,只有 Anthropic 的文件可以。另外三个地址的查询时间为 UTC 04:42:28 至 04:42:44:

IP来源verifiedoperatornamecategory评分、处置
216.73.216.10Anthropic 的文件trueAnthropicClaudeBotai0,allow
107.178.192.1Google 用户触发的抓取器文件trueGoogleGoogleUserTriggeredFetcherfetcher0,allow
104.43.54.127DuckDuckGo 的两份文件trueDuckDuckGoDuckAssistBotai0,allow
31.13.64.1Meta 的网络,AS32934falseMetaFacebook-Botsocial_preview0,allow

现在追踪一个请求。假设某个请求从 104.43.54.127 声称自己是 DuckDuckBot,这个地址以 /32 的形式同时列在 DuckDuckGo 的两份文件中。查询结果为 verified: true 和 operator: "DuckDuckGo",但 name: "DuckAssistBot",category: "ai"。如果策略写成“放行搜索 bot,对 AI bot 限速”,并且以名称或类别为依据,就会限制 DuckDuckGo 真正的搜索爬虫。如果以声称的 bot 及其运营方为依据,请求就能通过。我们原本预期得到 DuckDuckBot 这个名称,结果却是 DuckAssistBot:名称字段告诉我们的是最后加载的是哪份文件,而不是来访的是哪个 bot。

Meta 是另一个陷阱。我们按 ASN 匹配 Meta 的网络(AS32934),所以 is_crawler 为 true,但 verified 为 false,verification_method 为 "none"。请将其视为未验证。我们的文档列出了各个爬虫字段及其含义。

一份文件可能覆盖多个 bot,因此策略应以运营方为依据

先将声称的 User-Agent 映射到运营方,再要求 verified: true 且运营方一致。切勿将 crawler.name 或 category 作为判断开关,因为一份文件可能代表多个 bot:

  • DuckDuckGo:两份文件,一份列表。我们的扫描器第二个加载 duckassistbot.json,后写入者覆盖先写入者,因此每个 DuckDuckGo 地址都带有 DuckAssistBot 标签。
  • Anthropic:ClaudeBot、Claude-User 和 Claude-SearchBot 共用一份文件。Anthropic 的爬虫帮助页面写道:“If a crawler has a source IP address on this list, it indicates that the crawler is coming from Anthropic.”(如果某个爬虫的源 IP 地址在此列表中,则表明该爬虫来自 Anthropic。)因此,匹配意味着已验证为 Anthropic;具体是哪个 bot,由 User-Agent 告诉您。
  • Google:常用爬虫文件以 Googlebot 这一个标签覆盖了多个 Google 爬虫。

仅凭 is_crawler 也不足以用于白名单,因为对于 Meta 的未验证匹配,它同样为 true。此外,API 永远看不到您的请求头。它只接收 IP,所以检查中“声明”这一侧始终在您的代码中执行。

四步构建爬虫白名单

分四步构建:将您允许的每个 User-Agent 映射到其运营方,加载该运营方的文件,用这些文件检查 IP,并把每个未通过的声明交给限速器。

  1. 声明映射表。列出您允许的 User-Agent 标识(较老的 WAF 称之为 whitelist),以及 IP 必须出现在其文件中的运营方。
  2. 文件。要么用下面的脚本构建您自己的合并列表,要么对每个新 IP 调用一次查询,并将结论缓存几个小时(而不是几周),因为 IP 段会变化。
  3. 匹配。只用声称的运营方的前缀来检查 IP。
  4. 未验证路径。不要用 403 回应。对无法验证的请求限速,这样使用新前缀的真实爬虫只会变慢,而不会消失。

为什么按运营方而不是按文件?因为有些运营方根本无法按文件精确绑定。Anthropic 的三个 bot 共用一份文件,DuckDuckGo 的两个 bot 共用一份列表,所以要求“必须在 Claude-SearchBot 自己的文件中”的检查没有可匹配的对象。按运营方匹配会在 Google、OpenAI、Perplexity 和 Mistral 上损失一点精度,因为它们的文件是分开的;作为交换,它在共享文件上永远不会误判。

两条规则。精确匹配已发布的前缀,绝不按 ASN 匹配:在我们的查询中,Microsoft 的 AS8075 承载着 Bingbot、GPTBot、ChatGPT-User 和 DuckDuckGo,把它加入白名单就等于放行所有 Azure 客户。并且绝不仅凭 User-Agent 加入白名单。对于没有文件的 bot,如果运营方提供了说明,请使用正向确认的反向 DNS。

构建脚本会抓取全部 19 份文件,按运营方对前缀分组,并写入 allowlist.json,每份文件都记录抓取时间。如果某份文件下载失败、解析失败、返回为空,或者缩减到不足上一次有效副本的一半,脚本会保留该文件之前的前缀。GeoIPHub 的扫描器也是这样做的,只是为每份文件设置了固定的最小前缀数。

GeoIPHub API
// build-allowlist.mjs: Node 18+, no dependencies. Run once a day. import fs from "node:fs"; const FEEDS = { Google: [ "https://developers.google.com/static/crawling/ipranges/common-crawlers.json", "https://developers.google.com/static/crawling/ipranges/special-crawlers.json", "https://developers.google.com/static/crawling/ipranges/user-triggered-fetchers.json", "https://developers.google.com/static/crawling/ipranges/user-triggered-fetchers-google.json", "https://developers.google.com/static/crawling/ipranges/user-triggered-agents.json", ], Microsoft: ["https://www.bing.com/toolbox/bingbot.json"], Apple: ["https://search.developer.apple.com/applebot.json"], DuckDuckGo: [ "https://duckduckgo.com/duckduckbot.json", "https://duckduckgo.com/duckassistbot.json", ], OpenAI: [ "https://openai.com/gptbot.json", "https://openai.com/chatgpt-user.json", "https://openai.com/searchbot.json", ], Anthropic: ["https://claude.com/crawling/bots.json"], Perplexity: [ "https://www.perplexity.ai/perplexity-user.json", "https://www.perplexity.ai/perplexitybot.json", ], Mistral: [ "https://mistral.ai/mistralai-user-ips.json", "https://mistral.ai/mistralai-index-ips.json", ], CommonCrawl: ["https://index.commoncrawl.org/ccbot.json"], Ahrefs: ["https://api.ahrefs.com/v3/public/crawler-ip-ranges"], }; const OUT = "allowlist.json"; const previous = fs.existsSync(OUT) ? JSON.parse(fs.readFileSync(OUT, "utf8")) : { files: {} }; const files = {}; for (const [operator, urls] of Object.entries(FEEDS)) { for (const url of urls) { try { const res = await fetch(url, { signal: AbortSignal.timeout(15000) }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const body = await res.json(); const prefixes = (body.prefixes || []) .map((p) => p.ipv4Prefix || p.ipv6Prefix) .filter(Boolean); if (prefixes.length === 0) throw new Error("no prefixes in file"); const last = previous.files[url]; // A real shrink this large is rare: check it by hand before you trust it. if (last && prefixes.length < last.prefixes.length / 2) { throw new Error(`${prefixes.length} prefixes, last good copy had ${last.prefixes.length}`); } files[url] = { operator, prefixes, file_date: body.creationTime || null, fetched_at: new Date().toISOString(), }; } catch (err) { // Fail safe: a broken fetch keeps yesterday's prefixes for that file. if (previous.files[url]) files[url] = previous.files[url]; console.error(`${url}: ${err.message}; ${files[url] ? "kept previous prefixes" : "no previous copy"}`); } } } fs.writeFileSync(`${OUT}.tmp`, JSON.stringify({ built_at: new Date().toISOString(), files }, null, 1)); fs.renameSync(`${OUT}.tmp`, OUT); console.log(`${Object.keys(files).length} files written to ${OUT}`);

用一行 cron 即可定时运行,例如 20 5 * * * cd /srv/bots && node build-allowlist.mjs。策略检查既可以读取该文件,也可以读取查询响应,两条路径都以声称的 bot 的运营方为依据:

GeoIPHub API
// check-claim.mjs: decide whether a bot claim is proven. import net from "node:net"; // Claimed User-Agent token, and the operator whose file must contain the IP. // Not exhaustive; add the bots you allow. const CLAIMS = [ ["googlebot", "Google"], ["adsbot-google", "Google"], ["google-agent", "Google"], ["bingbot", "Microsoft"], ["applebot", "Apple"], ["duckduckbot", "DuckDuckGo"], ["duckassistbot", "DuckDuckGo"], ["gptbot", "OpenAI"], ["oai-searchbot", "OpenAI"], ["chatgpt-user", "OpenAI"], ["claudebot", "Anthropic"], ["claude-searchbot", "Anthropic"], ["claude-user", "Anthropic"], ["perplexitybot", "Perplexity"], ["perplexity-user", "Perplexity"], ["mistralai-user", "Mistral"], ["mistralai-index", "Mistral"], ["ccbot", "CommonCrawl"], ["ahrefsbot", "Ahrefs"], ]; function findClaim(userAgent) { const ua = (userAgent || "").toLowerCase(); return CLAIMS.find(([token]) => ua.includes(token)) || null; } // Path 1: your own allowlist.json from build-allowlist.mjs. export function loadLists(allowlist) { const lists = {}; for (const file of Object.values(allowlist.files)) { lists[file.operator] ||= new net.BlockList(); for (const cidr of file.prefixes) { const [addr, len] = cidr.split("/"); lists[file.operator].addSubnet(addr, Number(len), net.isIPv6(addr) ? "ipv6" : "ipv4"); } } return lists; } export function checkWithLists(userAgent, ip, lists) { const claim = findClaim(userAgent); if (!claim) return { claimed: null, verified: false }; const family = net.isIPv6(ip) ? "ipv6" : "ipv4"; return { claimed: claim[0], verified: lists[claim[1]]?.check(ip, family) === true }; } // Path 2: one lookup per new IP, using the API's crawler fields. export async function lookup(ip, apiKey) { try { const res = await fetch(`https://api.geoiphub.com/v1/lookup/${ip}`, { headers: { "x-api-key": apiKey }, signal: AbortSignal.timeout(2000), }); return res.ok ? await res.json() : null; } catch { return null; // a failed lookup proves nothing: treat it as unverified } } export function checkClaim(userAgent, result) { const claim = findClaim(userAgent); if (!claim) return { claimed: null, verified: false }; const c = result?.threat?.crawler; return { claimed: claim[0], verified: c?.verified === true && c?.operator === claim[1] }; }

我们用 2026 年 10 月 29 日的文件和查询结果运行了这两条路径,并加上了各种失败情形。GPTBot 用例使用的是 45.33.32.156,即 Nmap 的公共测试主机,它从未发送过此类请求。检查是按运营方而不是按 bot 进行的:来自 Google 抓取器文件中某个地址的 Googlebot 声明,同样会作为 Google 通过。

GeoIPHub API
PASS ClaudeBot UA, 216.73.216.10 verified (name ClaudeBot) PASS Claude-SearchBot UA, 216.73.216.10 verified as Anthropic (name ClaudeBot) PASS DuckDuckBot UA, 104.43.54.127 verified (name DuckAssistBot) PASS AhrefsBot UA, 5.39.1.230 verified PASS Googlebot UA, 66.249.66.1 verified PASS GPTBot UA, 45.33.32.156 not verified (no file match) PASS ChatGPT-User UA, 66.249.66.1 not verified (operator is Google) PASS facebookexternalhit UA, 31.13.64.1 no claim in the map PASS Browser UA, 216.73.216.10 no claim PASS Lookup error, ClaudeBot UA not verified 10/10 passed, lookup path and allowlist path agree builder, bots.json forced to fail: kept previous prefixes (14) builder, bingbot.json returns HTML: kept previous prefixes (28) builder, applebot.json returns []: kept previous prefixes (24) builder, chatgpt-user.json shrinks to 1: kept previous prefixes (235)

这段代码负责放行这一侧。如果要执行按 bot 拦截的策略,请参阅我们 AI 爬虫指南中的 nginx 和 Express 配置。

已验证的 bot 仍可能是恶意 bot 吗?AhrefsBot 的答案是肯定的

是的。验证证明的是谁在运营这个地址,而不是这个地址干净或受欢迎。AhrefsBot 的 5.39.1.230 同时说明了这两点(2026 年 10 月 29 日 UTC 04:42:51):

字段值
threat.crawler.verifiedtrue
threat.crawler.operatorAhrefs
threat.crawler.categoryseo
threat.is_spammertrue
threat.dnsbl_sourceszen.spamhaus.org
scoring.fraud_score35
scoring.recommended_actionreview
scoring.detection_methodsdatacenter_blocklisted, no_ptr_datacenter, verified_crawler, known_spammer

已验证爬虫信号会减去 28.5 分(在 0.95 置信度下减 30 分),但它无法抵消黑名单记录;风险评分原因指南展示了具体算法。我们为这个地址保存了两个较早的值:10 月 19 日为 59、step_up,当时还触发了一条滥用记录;自 10 月 22 日起为 35、review。当我们在 10 月 19 日调查这个地址时,RIPE 的注册信息显示该 /27 网段注册在 Ahrefs 名下,位于 OVH 的一个地址块内。

AhrefsBot 能否进入,由您的白名单决定。评分告诉您的是,它所在的 IP 段有过不良记录。许多网站用不上 SEO 爬虫,也有许多网站需要它们,所以这个决定由您来做。

按设计就会忽略 robots.txt 的良性 bot

“遵守 robots.txt”并不能用来判断一个 bot 是否良性,因为运营方自己就说明,他们的用户触发抓取器可能不遵守它:

  • Google:“Because the fetch was requested by a user, these fetchers generally ignore robots.txt rules.”(由于抓取是用户请求的,这些抓取器通常会忽略 robots.txt 规则。)(Google 用户触发的抓取器)
  • OpenAI 关于 ChatGPT-User:“Because these actions are initiated by a user, robots.txt rules may not apply.”(由于这些操作由用户发起,robots.txt 规则可能不适用。)(OpenAI bots)
  • Perplexity 关于 Perplexity-User:“Since a user requested the fetch, this fetcher generally ignores robots.txt rules.”(由于抓取是用户请求的,该抓取器通常会忽略 robots.txt 规则。)(Perplexity 爬虫)

三者的理由相同:这类抓取是代表某个人进行的,拦截它就等于拦截了这个人的请求。一个跳过您 robots.txt 的已验证抓取器,是在按文档说明行事,而不是行为不端。

robots.txt 只是请求;白名单才是强制执行。如果您想把某个用户触发的抓取器挡在门外,就需要在边缘层设置规则,而不是在文本文件里加一行。关于 OpenAI 每个 bot 的用途以及拦截每个 bot 的代价,请参阅我们的 OpenAI 对比文章。

列表有多新?文件日期、每日抓取与两天延迟

列表的新鲜程度等于运营方的最后一次编辑加上您的抓取时间。对于 GeoIPHub 的 API,这意味着每天抓取一次,一次变更最多约需两天才会生效。

以下是具体机制,依据 GeoIPHub 扫描器的代码和配置,核实于 2026 年 10 月 29 日。爬虫步骤每天最多抓取每份文件一次。如果抓取失败,或者返回的前缀少于该文件的最小值,扫描器会保留最后一次有效的 IP 段。运营方删除的前缀,会在下一次成功抓取及随后的每日重建之后停止通过验证。查询数据库每天 UTC 00:00 重建,大约在 UTC 04:00 上线。

实践规则:已验证的结论缓存几个小时,每天重新抓取文件,并预期新增的前缀在最长约两天内无法通过验证。这也是未验证路径应交给限速器而不是直接拦截的另一个原因。

在我们的核查中,Perplexity 是唯一在文档中提到更新周期的运营方:“These addresses are updated regularly and should be the source of truth for your WAF configurations.”(这些地址会定期更新,应作为您 WAF 配置的唯一可信来源。)Google 的验证页面没有说明频率。我们在 2026 年 10 月 29 日抓取的文件日期从 2024 年 1 月(Microsoft)到 2026 年 10 月 28 日(Google 和 Perplexity)不等。日期长期不变并不是错误;有些机群就是不会变动。

我们这边有一个不足:API 不会显示匹配的是哪份文件,也不会显示我们何时抓取了它。如果您需要这样的审计记录,请运行构建脚本并保留其 fetched_at 值。

没有公开列表的 bot,以及如何应对

有些您可能想放行的 bot 并没有发布 GeoIPHub 可加载的文件,因此这份列表无法验证它们:

  • OAI-AdsBot:OpenAI 对它有文档说明,并发布了 adsbot.json,但我们的扫描器暂未加载。如果您在 ChatGPT 上投放广告,请把它加入您自己的构建脚本。
  • Amazonbot:Amazon 在一个网页中列出其 IP 段,没有可下载的文件。我们没有加载它。
  • Meta:Meta 的爬虫页面写道:“Add to your allow list either the user agent strings or the IP addresses (more secure) used by the crawler”(将爬虫使用的 user agent 字符串或 IP 地址(更安全)加入您的白名单),但没有提供 IP 段文件。我们仅按 ASN 匹配其网络,属于未验证。
  • Yandex 和 Baidu:仅支持反向 DNS。Yandex 的指南描述了检查方法:反向 DNS 名称必须以 yandex.ru、yandex.net 或 yandex.com 结尾,并且对该名称进行正向查询必须返回同一个 IP。
  • Bytespider:我们没有找到 ByteDance 发布的 IP 段文件。
  • 可用性监控和支付 webhook:许多服务会发布自己的列表。Stripe 以 JSON 格式发布 webhook IP,并在其 IP 地址页面中加以说明。请使用供应商自己的列表;它们不是爬虫,也不在我们的数据源中。
  • 对请求进行签名的 bot:Web Bot Auth 让 bot 可以用加密签名而不是 IP 来证明身份,详见我们的爬虫验证指南。Cloudflare 的已验证 bot 目录接受通过 Web Bot Auth 验证的 bot,或通过已发布 IP 列表并使用稳定 User-Agent 验证的 bot。

应对方法:运营方提供反向 DNS 方法的,就使用该方法;对于各类服务,使用供应商自己的列表;其余一律交给限速器。

今晚就运行构建脚本,或者把日志中的某个 IP 粘贴到 IP 查询工具中,看看其 Crawler 一行显示的是“Verified crawler”还是“Unverified crawler”。请求头中的名称只是声明;运营方的文件才是证明。

常见问题

什么是已验证爬虫 IP 列表?

这是一份根据 bot 运营方为自家爬虫发布的 IP 段文件构建的列表。GeoIPHub 加载了 10 家运营方的 19 份此类文件,包括 Google、Microsoft、Apple、OpenAI 和 Anthropic;OpenAI 还发布了第 20 份文件 adsbot.json,我们暂未加载。当一个请求的 User-Agent 声明了某个 bot,且其 IP 位于该运营方的文件中时,该请求才算来自已验证的爬虫。

IP 查询能看到 User-Agent 吗?

不能。GeoIPHub 的查询只接收 IP。它可以告诉您该地址位于 Anthropic 或 Google 的文件中,再由您自己的代码将该运营方与 User-Agent 声称的 bot 进行比对。

已验证的 bot 仍可能是恶意 bot 吗?

可能。2026 年 10 月 29 日,AhrefsBot 的 5.39.1.230 与 Ahrefs 发布的 IP 段匹配,同时也被列入 Spamhaus ZEN,在 GeoIPHub 的 API 中得分 35,处置建议为 review。验证只能告诉您是谁在运营这个地址,而不能告诉您是否应该放行。

爬虫 IP 段多久变化一次?

取决于运营方,而且大多数运营方并未说明。2026 年 10 月 29 日,各文件中的日期从 2024 年 1 月(Microsoft)到 2026 年 10 月 28 日(Google 和 Perplexity)不等。GeoIPHub 每天重新抓取所有文件,一次变更最多约需两天才会在其 API 中生效。

应该按 ASN 将爬虫加入白名单吗?

不应该。许多爬虫运行在共享云上:Microsoft 的网络承载着 Bingbot、GPTBot 和 DuckDuckGo 的 bot,把它加入白名单就等于放行该云上的所有客户。请精确匹配每家运营方文件中的前缀。

哪些 bot 无法通过 IP 列表验证?

运营方没有发布文件的 bot,例如 Yandex 和 Baidu(改用反向 DNS)、Meta(没有 IP 段文件;GeoIPHub 按 ASN 匹配其网络,属于未验证)以及 Bytespider。Amazon 只在一个网页中列出 Amazonbot 的 IP 段。对无法验证的请求进行限速。

作者

GeoIPHub 团队

GeoIPHub API 背后的团队

由 GeoIPHub 团队撰写,即构建 GeoIPHub IP 情报 API 及其扫描器的团队。草稿在 AI 辅助下完成,并由团队编辑;除非标注为示例,API 示例均为针对线上 API 的真实查询。

分享本文
更多文章

相关 文章