curl -sS -X POST "https://api.adscrawl.net/html" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": { "width": 1280, "height": 720 },
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows"
}'
const response = await fetch("https://api.adscrawl.net/html", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({
url: "https://example.com/article",
contentMode: "json",
waitUntil: "domcontentloaded",
viewport: { width: 1280, height: 720 },
locale: "en-US",
countryCode: "GLOBAL",
userAgentMode: "random",
userAgentOs: "windows",
}),
});
if (!response.ok) {
const err = await response.json();
throw new Error(`${response.status} ${err.code}: ${err.error}`);
}
const article = await response.json();
console.log(article.title, article.byline);
import httpx, json
response = httpx.post(
"https://api.adscrawl.net/html",
headers={
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
json={
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": {"width": 1280, "height": 720},
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows",
},
)
response.raise_for_status()
article = response.json()
print(article["title"], article["byline"])
{
"title": "Example Article",
"byline": "OpenAI",
"excerpt": "A concise article summary.",
"siteName": "Example",
"lang": "en",
"dir": null,
"content": "<div><p>Readable body...</p></div>",
"textContent": "Readable body...",
"length": 2487,
"publishedTime": null
}
# Example Article
Readable body...
- key point one
- key point two
{
"error": "Insufficient credits",
"code": "INSUFFICIENT_CREDITS",
"balance": 0,
"requiredCredits": 1
}
{
"error": "Readable article content was not found",
"code": "READABILITY_CONTENT_NOT_FOUND"
}
{
"error": "countryCode is not supported",
"code": "INVALID_COUNTRY_CODE"
}
{
"error": "Dynamic country/region routing is unavailable",
"code": "DYNAMIC_PROXY_NOT_CONFIGURED"
}
浏览器任务
渲染 HTML、Markdown 或 Article JSON
通过住宅代理加载任意公开 URL,返回完整渲染的原始 HTML、可读 Markdown 或结构化文章 JSON。
POST
/
html
curl -sS -X POST "https://api.adscrawl.net/html" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": { "width": 1280, "height": 720 },
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows"
}'
const response = await fetch("https://api.adscrawl.net/html", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({
url: "https://example.com/article",
contentMode: "json",
waitUntil: "domcontentloaded",
viewport: { width: 1280, height: 720 },
locale: "en-US",
countryCode: "GLOBAL",
userAgentMode: "random",
userAgentOs: "windows",
}),
});
if (!response.ok) {
const err = await response.json();
throw new Error(`${response.status} ${err.code}: ${err.error}`);
}
const article = await response.json();
console.log(article.title, article.byline);
import httpx, json
response = httpx.post(
"https://api.adscrawl.net/html",
headers={
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
json={
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": {"width": 1280, "height": 720},
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows",
},
)
response.raise_for_status()
article = response.json()
print(article["title"], article["byline"])
{
"title": "Example Article",
"byline": "OpenAI",
"excerpt": "A concise article summary.",
"siteName": "Example",
"lang": "en",
"dir": null,
"content": "<div><p>Readable body...</p></div>",
"textContent": "Readable body...",
"length": 2487,
"publishedTime": null
}
# Example Article
Readable body...
- key point one
- key point two
{
"error": "Insufficient credits",
"code": "INSUFFICIENT_CREDITS",
"balance": 0,
"requiredCredits": 1
}
{
"error": "Readable article content was not found",
"code": "READABILITY_CONTENT_NOT_FOUND"
}
{
"error": "countryCode is not supported",
"code": "INVALID_COUNTRY_CODE"
}
{
"error": "Dynamic country/region routing is unavailable",
"code": "DYNAMIC_PROXY_NOT_CONFIGURED"
}
使用
POST /html 在真实浏览器中加载任意公开 URL,并以应用所需的格式返回渲染后的内容。选择 "html" 获取完整 DOM,选择 "markdown" 获取干净可读的文章内容,或选择 "json" 获取包含标题、作者、摘要和正文结构的 Readability 结构化数据。所有请求均通过住宅代理并配合随机浏览器指纹进行路由。
string
必填
目标页面 URL。仅支持 80 和 443 端口。
string
控制响应格式。可选值:
"html"(默认)、"markdown"、"json"。"markdown" 和 "json" 均使用 Readability 提取可读文章内容。string
在提取前等待第一个匹配的 CSS 元素出现。当
contentMode 为 "html" 时,仅返回该元素的 HTML。当为 "markdown" 或 "json" 时,Readability 将针对该元素运行。如果未找到选择器,则返回 422 CONTENT_SELECTOR_NOT_FOUND。string
在提取内容前等待的导航事件。默认值为
"load"。| Value | Behaviour |
|---|---|
"domcontentloaded" | 等待 DOMContentLoaded。HTML 已解析,无需等待图片等次要资源。推荐用于 HTML 提取。 |
"load" | 等待页面和依赖资源(图片、样式表)加载完成后的 window.load。 |
"networkidle" | 等待至少 500 毫秒内没有任何网络连接。长轮询、分析脚本或懒加载资源可能导致超时。 |
number
任务完成的最长等待时间,单位为毫秒。必须是正整数且不超过
3,600,000。超出范围的值将回退为服务器默认值。string
浏览器语言环境,例如
"en-US" 或 "zh-CN"。会影响 navigator.language 和 Accept-Language header。string
IANA 时区标识符,例如
"Asia/Shanghai" 或 "America/New_York"。object
自定义代理配置。不能与
countryCode 同时使用。提供 server 或拆分形式(protocol + host + port)。不能将凭据嵌入 server 中。string
管理的住宅代理区域。不能与
proxy 同时使用。"GLOBAL":从 15 个热门区域中动态选择出口。- 两位字母国家代码(例如
"US"、"DE"):优先使用该区域的受信任代理,并支持动态回退。 - 省略:自动随机选择受信任代理。
string
"random" 让服务器从其库中选择 User-Agent。未显式提供 userAgent 的请求已默认使用 "random"。string
当
userAgentMode 为 "random" 时使用的操作系统。可选值:"windows"(默认)或 "macos"。string
显式指定 User-Agent 字符串。覆盖随机选择。
object
浏览器指纹设置。省略时,所有信号默认随机,同时保持操作系统、GPU、CPU、内存、字体和设备信号的一致性。
显示 fingerprint 字段
显示 fingerprint 字段
string
"forward" 使用代理出口地址。也可使用 "real" 或 "disabled"。string
"random" 或 "real"。控制 WebGL 厂商和渲染器元数据。string
"random"、"real" 或 "disabled"。随机模式遵循 WebGL GPU 设置。string
"random" 或 "real"。控制 WebGL 图像噪声。string
"random" 或 "real"。控制 canvas 噪声。string
"random" 或 "real"。控制音频指纹噪声。string
"random" 或 "real"。控制布局测量噪声。string
"random" 或 "real"。返回与操作系统匹配的语音列表。string
"random" 或 "real"。返回与操作系统匹配的字体列表。string
"random" 或 "real"。生成一致的 CPU 线程数和内存配对。string
"random"、"enabled" 或 "disabled"。array
在导航前注入浏览器上下文的 Cookie 列表。每个 Cookie 对象需要
name、value 和 domain。响应
string
从页面提取的文章标题。
string
作者名称或署名(如果存在)。
string
文章的简短摘要或描述。
string
网站名称(如果可用)。
string
文章的语言代码,例如
"en"。string
文本方向,例如
"ltr" 或 "rtl"。如果未检测到则为 null。string
文章正文的清理后 HTML。
string
文章正文的纯文本版本,空白字符已规范化。
number
textContent 的字符数。string
ISO 8601 发布日期时间戳,如果未找到则为
null。| Code | Meaning |
|---|---|
200 | 成功。根据 contentMode 返回 text/html、text/markdown 或 application/json。 |
400 | JSON、URL、contentMode、Cookie、代理、区域或 User-Agent 参数无效。请求体超过 1 MiB。 |
401 | x-api-key 缺失或无效。 |
402 | 余额不足。返回 INSUFFICIENT_CREDITS、balance 和 requiredCredits。 |
422 | 未找到选择器(CONTENT_SELECTOR_NOT_FOUND)或缺少可读内容(READABILITY_CONTENT_NOT_FOUND)。 |
429 | 任务请求频率受限。 |
502 | 代理不可达或目标 HTTP 失败。 |
503 | 队列、Worker、管理代理或 User-Agent 资源不可用。 |
504 | 任务、导航或代理连接超时。 |
500 | 未分类的任务执行失败。 |
一次请求验证后会消耗 1 积分,在任务入队之前扣除。请求体限制为 1 MiB。
更多示例
curl -sS -X POST "https://api.adscrawl.net/html" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com",
"contentMode": "html",
"selector": "main",
"waitUntil": "domcontentloaded",
"countryCode": "US"
}'
const response = await fetch("https://api.adscrawl.net/html", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({
url: "https://example.com",
contentMode: "html",
selector: "main",
waitUntil: "domcontentloaded",
countryCode: "US",
}),
});
const html = await response.text();
console.log(html);
import httpx
response = httpx.post(
"https://api.adscrawl.net/html",
headers={
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
json={
"url": "https://example.com",
"contentMode": "html",
"selector": "main",
"waitUntil": "domcontentloaded",
"countryCode": "US",
},
)
response.raise_for_status()
print(response.text)
curl -sS -X POST "https://api.adscrawl.net/html" \
-H "content-type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": { "width": 1280, "height": 720 },
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows"
}'
const response = await fetch("https://api.adscrawl.net/html", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
body: JSON.stringify({
url: "https://example.com/article",
contentMode: "json",
waitUntil: "domcontentloaded",
viewport: { width: 1280, height: 720 },
locale: "en-US",
countryCode: "GLOBAL",
userAgentMode: "random",
userAgentOs: "windows",
}),
});
if (!response.ok) {
const err = await response.json();
throw new Error(`${response.status} ${err.code}: ${err.error}`);
}
const article = await response.json();
console.log(article.title, article.byline);
import httpx, json
response = httpx.post(
"https://api.adscrawl.net/html",
headers={
"content-type": "application/json",
"x-api-key": "YOUR_API_KEY",
},
json={
"url": "https://example.com/article",
"contentMode": "json",
"waitUntil": "domcontentloaded",
"viewport": {"width": 1280, "height": 720},
"locale": "en-US",
"countryCode": "GLOBAL",
"userAgentMode": "random",
"userAgentOs": "windows",
},
)
response.raise_for_status()
article = response.json()
print(article["title"], article["byline"])
{
"title": "Example Article",
"byline": "OpenAI",
"excerpt": "A concise article summary.",
"siteName": "Example",
"lang": "en",
"dir": null,
"content": "<div><p>Readable body...</p></div>",
"textContent": "Readable body...",
"length": 2487,
"publishedTime": null
}
# Example Article
Readable body...
- key point one
- key point two
{
"error": "Insufficient credits",
"code": "INSUFFICIENT_CREDITS",
"balance": 0,
"requiredCredits": 1
}
{
"error": "Readable article content was not found",
"code": "READABILITY_CONTENT_NOT_FOUND"
}
{
"error": "countryCode is not supported",
"code": "INVALID_COUNTRY_CODE"
}
{
"error": "Dynamic country/region routing is unavailable",
"code": "DYNAMIC_PROXY_NOT_CONFIGURED"
}