跳到正文
基础工具1 credit

extract_links

发现并提取网页中的所有链接。非常适合站点地图生成、链接分析和爬取工作流。

使用场景

生成站点地图

通过提取所有内部链接构建全面的站点地图

为爬取发现链接

在网页爬取工作流中找出所有要访问的 URL

内部链接分析

分析内部链接结构以进行 SEO 优化

失效链接检测

查找并校验页面上的所有链接

Endpoint

POST/api/v1/tools/extract_links
Auth Required
Free 计划 1 req/s
1 credit

Parameters

NameTypeRequiredDefaultDescription
url
stringOptional-
要抓取并从中提取链接的页面。`url` 与 `html` 二者必填其一。
Example: https://example.com
html
stringOptional-
直接解析的原始 HTML,替代抓取。请配合 `base_url` 使用,以便相对 href 能够解析。
Example: <a href='/about'>About</a>
base_url
stringOptional-
解析相对链接所用的基地址,优先于页面自身的 `<base href>`。抓取时默认使用页面的 `<base href>`,没有则使用 `url`;传入 `html` 时请一并提供。
Example: https://example.com
include_internal
booleanOptionaltrue
包含指向同一主机的链接。
Example: true
include_external
booleanOptionaltrue
包含指向其他主机的链接。设为 false 可只保留内部链接。
Example: true
filter_external
booleanOptionalfalse
MCP 工具用于只返回出站链接的参数名:`true` 等同于 `include_internal: false`,并优先于它。这是一个别名,便于同一请求体在两个接口上通用。它不会移除类型为 `other`、`anchor` 或 `relative` 的链接。
Example: true
filter_domains
arrayOptional-
仅保留主机与这些域名之一匹配的链接。
Example: ["docs.example.com"]
include_anchors
booleanOptionalfalse
包含形如 `#section` 的纯片段链接。
Example: false
deduplicate
booleanOptionaltrue
将重复的 URL 合并为一条,比较时忽略片段和末尾斜杠(`/a`、`/a/` 和 `/a#x` 视为同一链接);保留首次出现的那条。
Example: true
include_metadata
booleanOptionaltrue
返回每个链接的 `title` 属性以及 `domains` 计数表。无论是否开启,每条链接记录都带有 `href`、`text`、`type`、`domain`、`rel` 和 `original_href`,与 MCP 工具返回的结构相同。
Example: true
respect_robots
booleanOptionaltrue
遵守目标站点的 robots.txt。保持 `true` 时,robots.txt 对 `CrawlForge` 禁止的路径会在抓取之前以 403 拒绝,且不扣除 credits。仅在你与目标站点另有约定时才设为 `false`——此时响应会带上一条 `warnings`,并且该覆盖会记录到你的 API key 上。
Example: true
escalate
booleanOptionalfalse
选择加入:当对 `url` 的普通抓取遇到的是拦截墙而不是页面时——Cloudflare、Amazon、DataDome、PerimeterX、Akamai 或 Vercel 的挑战页、单纯的 403、429 或 444,或以 2xx 返回的空壳页面或错误占位页——自动通过 stealth 浏览器重试一次。普通抓取始终先执行;404、5xx、PDF 等二进制内容,或 `Retry-After` 等待期仍未结束的主机,永远不会触发升级;`html` 输入不会被抓取。链接从渲染出的 HTML 中读取,因此响应结构不变,另外只要设置了此参数就会带上 `escalated`,渲染实际执行时还会带上 `stealth: { engine, vendor_detected }`。升级复用与 [stealth_mode](/docs/api-reference/tools/stealth-mode) 相同的 stealth 路径和同一道 robots.txt 校验,不会新增任何针对反爬防护的处理手段;若渲染同样被拒,结果仍作为被拦截的页面返回并带有 `escalated: true`,且不计费。仅在渲染真正执行时加收 5 credits。
Example: true
escalate_engine
stringOptionalplaywright
升级阶段使用的浏览器引擎:"playwright"(默认)或 "camoufox"(基于 Firefox,抗检测能力更强;仅在后端已安装时可用)。除非 `escalate` 为 `true` 且普通抓取被拦下,否则忽略此参数。
Example: camoufox
max_inline_chars
numberOptional40000
内联返回的最大结果大小,以其 JSON 的字符数计(1,000-10,000,000)。超过后,响应会携带 `preview`(格式化 JSON 的前 `max_inline_chars` 个字符)、`result_handle`、`total_chars`、`truncated: true` 和 `expires_at`,其余部分由 [read_result](/docs/api-reference/tools/read-result) 读取,每次调用 1 credit。已存储的结果保留 1 小时。
Example: 40000

抓取 URL

  • 页面只抓取一次,超时时间为 15 秒。若返回 429 或 503 且 Retry-After 不超过 10 秒,会等待该时长后再抓取一次;Retry-After 更长或缺失时不重试。
  • 可读取 HTML、XHTML、XML 及所有 text/* 类型,未带 Content-Type 的响应按 HTML 读取。PDF、图片或其他二进制内容返回 415 UNSUPPORTED_CONTENT_TYPE,附带 next_step: "process_document",且不计费:请改用 process_document 读取。
  • JSON 响应体(application/json 或 *+json)不返回任何链接,并附带警告 the target returned application/json; it has no HTML links。
  • 在客户端渲染的页面——可见文本少于 200 个字符,且含有空的 <div id="root">、"app" 或 "__next",或文本说明页面需要 JavaScript("Enable JavaScript…")——在未执行 stealth 渲染时仍返回成功,data 中带有 rendered: false,warnings 中带有 page renders client-side; use scrape,以免把空壳页面误认为内容很短的页面。html 输入同样会做此检查。
  • 每次调用 1 credit。设置 escalate: true 时,预估上限为 6 credits;只有当普通抓取被拦下且升级阶段真正执行时,才会收取升级阶段的 5 credits。任何失败都不计费。

请求示例

cURL - 提取所有链接

terminalBash
curl -X POST https://crawlforge.dev/api/v1/tools/extract_links \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "include_internal": true,
    "include_external": false,
    "deduplicate": true
  }'

TypeScript - 仅内部链接

extractLinks.tsTypescript
// npm install crawlforge-sdk
import { CrawlForge } from 'crawlforge-sdk';

const client = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });

const result = await client.extractLinks({
  url: 'https://example.com',
  // Internal-only: keep include_internal, switch include_external off.
  include_internal: true,
  include_external: false,
  deduplicate: true,
});

// result.data is untyped in crawlforge-sdk 0.1 — its shape is the Response Example below.
const { base_url, extracted_from, links } = result.data as {
  base_url: string; extracted_from: string; links: unknown[];
};
console.log('Base URL:', base_url);
console.log('Extracted from:', extracted_from);

for (const link of links) console.log(link);

// Narrow to specific hosts instead of a blanket internal/external split.
const docsOnly = await client.extractLinks({
  url: 'https://example.com',
  filter_domains: ['docs.example.com'],
});

响应示例

200 OK210ms
{
"success": true,
"data": {
"links": [
{
"href": "https://example.com/about",
"text": "About",
"type": "internal",
"domain": "example.com",
"rel": null,
"original_href": "/about",
"title": "About us"
},
{
"href": "https://example.com/products",
"text": "Products",
"type": "internal",
"domain": "example.com",
"rel": null,
"original_href": "/products"
},
{
"href": "https://other-site.com/",
"text": "External Resource",
"type": "external",
"domain": "other-site.com",
"rel": "nofollow",
"original_href": "https://other-site.com"
},
{
"href": "mailto:hello@example.com",
"text": "Email us",
"type": "other",
"domain": null,
"rel": null,
"original_href": "mailto:hello@example.com"
}
],
"statistics": {
"total_links": 4,
"internal_links": 2,
"external_links": 1,
"anchor_links": 0,
"relative_links": 0,
"other_links": 1,
"unique_domains": 2
},
"domains": {
"example.com": 2,
"other-site.com": 1
},
"base_url": "https://example.com",
"extracted_from": "https://example.com/"
},
"credits_used": 1,
"credits_remaining": 999,
"processing_time": 210
}
Field Descriptions
data.links每个链接为 { href, text, type, domain, rel, original_href }(开启 include_metadata 时另含 title),与 MCP 工具返回的记录结构相同
data.links[].typeinternal(与页面同一主机)、external、anchor(#片段,需 include_anchors)、other(mailto:、tel:、javascript: 等非网页协议;除 mailto: 和 tel: 外 href 为 null)或 relative(html 输入且未提供 base_url)
data.links[].original_href页面上书写的原始 href;href 是解析后的绝对 URL
data.statistics按类型计数:total_links、internal_links、external_links、anchor_links、relative_links、other_links、unique_domains
data.domains每个域名的链接数(仅在开启 include_metadata 时返回)

错误处理

被反机器人拦截页阻挡(403、444 或 502)

无论 HTTP 状态码为何,目标返回的都是反机器人验证页面,而非实际内容。响应为 success: false,error.code 为 BLOCKED,附带指明 vendor(例如 cloudflare 或 akamai)及识别依据 evidence 的 blocked 对象,以及 next_step:extract_links with escalate:true, or stealth_mode operation:"scrape"。目标的状态码为 403、404、410、429、444 或 451 时原样返回,其他情况(包括以 200 返回的拦截页)均为 502。不扣除任何 credits。设置 escalate: true 时,会改为在 stealth 浏览器中渲染一次;若渲染同样被拒,同一错误会带有 escalated: true,且不带 next_step。

目标返回错误(502 Bad Gateway)

目标返回了 HTTP 错误,且未识别出反机器人拦截页。error.code 为 UPSTREAM_HTTP,消息为 Target answered HTTP <n>。403、404、410、429、444 或 451 会作为响应状态码原样透传;其他错误(5xx,或目标自身返回的 400、401)一律为 502,以免被误认为是你的请求或 API key 有问题。403、429 或 444 还会附带 next_step。不扣除任何 credits。

被 robots.txt 拦截(403 Forbidden)

目标站点的 robots.txt 对 CrawlForge 禁止了该路径。若你与目标站点另有约定,可设置 respect_robots: false 予以覆盖——该覆盖会记录到你的 API key 上。该覆盖不适用于列入 CrawlForge 永久排除名单的主机——无论 respect_robots 取何值,这类主机一律被拒绝。

不支持的内容类型(415 Unsupported Media Type)

目标返回的是 PDF、图片或其他二进制内容。error.code 为 UNSUPPORTED_CONTENT_TYPE,消息为 Unsupported content type <type>: extract_links reads HTML,next_step 为 process_document。不会读取响应体,不会触发升级,也不扣除任何 credits。

升级后端未配置(503 TOOL_NOT_AVAILABLE)

escalate: true 的 stealth 阶段运行在 CrawlForge 执行后端上。该后端未配置时,升级阶段返回 503,且不扣除任何 credits。

相关工具