> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/products/cn/web-api/scrape/ai-jie-xi.md).

# AI 解析

通过一个 Web API 请求，使用自然语言提示词或 JSON Schema 定义从任何页面提取结构化 JSON。

{% hint style="danger" %}
**会额外计费：** 使用 AI 解析您的 `/scrape` 请求会显著消耗更多账户额度。
{% endhint %}

Web API 可在获取目标网页的同一 HTTP 调用中提供结构化 JSON 抽取。结合 `output: ["json"]` 与根级 `json` 参数，可使用自然语言提示或严格的 OpenAPI / JSON Schema 定义来提取自定义字段。

<table><thead><tr><th width="143">字段</th><th>说明</th><th width="85">类型</th></tr></thead><tbody><tr><td><code>json.prompt</code></td><td>要提取字段的自然语言描述。</td><td>字符串</td></tr><tr><td><code>json.schema</code></td><td>一个 <a href="https://spec.openapis.org/oas/v3.1.0#schema-object">OpenAPI Schema Object</a> 结果必须符合。</td><td>对象</td></tr></tbody></table>

{% hint style="success" %}
使用 `prompt` 在探索页面且尚不清楚其结构时使用。使用 `schema` 在输出会供代码使用、且重命名或缺失的键会导致其出错时使用。
{% endhint %}

## 专用解析器 vs. 自定义 AI 抽取

Web API 支持两种解析机制，二者都会将数据返回在 `json` 键下，位于 `results[]` 数组中：

<table><thead><tr><th width="101">类型</th><th>方法</th><th>目标</th><th>适用于</th></tr></thead><tbody><tr><td>内置解析器</td><td>设置 <code>output: ["json"]</code> 而不提供根 <code>json</code> 对象。</td><td>带有预构建解析器的专用目标（例如， <code>/scrape/amazon/product</code>, <code>/scrape/google/search</code>).</td><td>由 Oxylabs 维护的标准化电商和 SERP 模式。</td></tr><tr><td>自定义 AI 抽取</td><td>设置 <code>output: ["json"]</code> 并传入 <code>json: { "prompt": ... }</code> 或 <code>json: { "schema": ... }</code> 对象。</td><td>每个路由，包括通用 <code>/v1/scrape</code> 以及没有专用解析器的目标。</td><td>自定义模式、独特的页面布局或非标准字段。</td></tr></tbody></table>

{% hint style="warning" %}
预构建解析器和自定义 AI 抽取都会填充 `results[].json` 响应负载中的键。如果您调用专用 scraper（例如 `/v1/scrape/amazon/product`）并使用 `output: ["json"]` 并使用自定义 `json` 抽取对象，自定义 AI 抽取将覆盖内置解析器输出。每次请求只能选择一种方式。
{% endhint %}

## 抽取模式： `prompt` vs. `schema`

使用自定义 AI 抽取时，根 `json` 对象可接受一个 `prompt` string 或一个 `schema` object。不要在同一请求中同时传入这两个参数。

### 自然语言（`prompt`)

传入描述所需字段的自然语言指令。AI 模型会检查页面 DOM，并构建匹配的 JSON 对象。

```json
{
  "url": "https://example.com/product/10928",
  "output": ["json"],
  "json": {
    "prompt": "提取主要商品标题、当前售价（数字）、货币代码，以及图片 URL 列表。"
  }
}
```

#### 何时使用

* 快速原型开发
* 实验性数据抽取
* 简单的扁平键值抽取，后续不严格强制精确数据类型

### 由模式定义（`schema`)

传入符合 OpenAPI 3.1 / OAS 3.0 Schema 规范的 JSON Schema 对象。抽取流程保证响应匹配您定义的类型、嵌套结构和必填字段。

```json
{
  "url": "https://example.com/product/10928",
  "output": ["json"],
  "json": {
    "schema": {
      "type": "object",
      "properties": {
        "title": { "type": "string" },
        "price": { 
          "type": "number", 
          "description": "显示给用户的最终折后价格，不含税。" 
        },
        "currency": { "type": "string" },
        "in_stock": { "type": "boolean" },
        "categories": {
          "type": "array",
          "items": { "type": "string" }
        }
      },
      "required": ["title", "price", "currency", "in_stock"]
    }
  }
}
```

#### 何时使用：&#x20;

* 生产流水线
* 自动化摄取数据库
* 强类型应用，其中缺失或意外的数据类型可能导致错误

## 常见 Schema 模式

### 1. 重复行和列表

通过将行对象包装在数组中来提取搜索结果、表格或商品列表：

```json
{
  "url": "https://example.com/search?q=laptop",
  "output": ["json"],
  "json": {
    "schema": {
      "type": "object",
      "properties": {
        "products": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "price": { "type": "number" },
              "rating": { "type": "number", "nullable": true },
              "url": { 
                "type": "string", 
                "description": "商品详情页的绝对 URL" 
              }
            },
            "required": ["name", "price", "url"]
          }
        }
      },
      "required": ["products"]
    }
  }
}
```

### 2. 标准化枚举和嵌套记录

使用以下方式将不同网站中的不同文本映射到固定的内部词汇： `枚举`:

```json
{
  "url": "https://example.com/product/123",
  "output": ["json"],
  "json": {
    "schema": {
      "type": "object",
      "properties": {
        "title": { "type": "string" },
        "availability": {
          "type": "string",
          "enum": ["in_stock", "out_of_stock", "preorder", "discontinued"],
          "description": "将页面用词映射为这些标准化状态字符串之一"
        },
        "seller": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "rating": { "type": "number", "nullable": true }
          },
          "required": ["name"]
        }
      },
      "required": ["title", "availability"]
    }
  }
}
```

例如， `枚举` 正是它让该字段在不同网站之间可比较：“In stock”、“Available now”和“Ships today”都会归为 `in_stock`，因此下游代码只需根据一个值分支，而无需匹配大量字符串。

### 3. 文章和博客元数据

提取发布元数据，用于结构化数据库存储：

```json
{
  "url": "https://example.com/blog/article",
  "output": ["json"],
  "json": {
    "schema": {
      "type": "object",
      "properties": {
        "headline": { "type": "string" },
        "author": { "type": "string", "nullable": true },
        "published_at": {
          "type": "string",
          "description": "格式为 ISO 8601 字符串（YYYY-MM-DD）的发布日期"
        },
        "tags": { "type": "array", "items": { "type": "string" } }
      },
      "required": ["headline", "published_at"]
    }
  }
}
```

## 本地化抽取

`location` 可直接应用于 AI 抽取。传入 ISO 3166-1 alpha-2 国家代码，以确保正确提取本地化价格和货币：

```bash
curl https://webapi.oxylabs.io/v1/scrape \
  -H "Authorization: Bearer $OXYLABS_WEB_API_KEY" \\
  -H 'Content-Type: application/json' \\
  -d '{
    "url": "https://sandbox.oxylabs.io/products/1",
    "output": ["json"],
    "location": "DE",
    "json": {
      "schema": {
        "type": "object",
        "properties": {
          "price": { "type": "number" },
          "currency": { "type": "string" }
        },
        "required": ["price", "currency"]
      }
    }
  }'
```

{% hint style="info" %}
没有 `location`， `货币` 你返回的是页面决定展示的那个。
{% endhint %}

## 响应模式

提取的 JSON 会在标准封装中的 `results[].json`:

{% code expandable="true" %}

```json
{
  "state": "done",
  "results": [
    {
      "json": {
        "currency": "€",
        "price": 91.99
      },
      "metadata": {
        "page": 1,
        "run_js": false,
        "url": "https://sandbox.oxylabs.io/products/1",
        "statuses": {
          "http_request": {
            "code": 200,
            "tag": "HTTP_OK"
          },
          "json_parse": {
            "code": 12000,
            "tag": "PARSE_SUCCESS"
          }
        }
      }
    }
  ],
  "params": {
    "url": "https://sandbox.oxylabs.io/products/1",
    "output": [
      "json"
    ],
    "json": {
      "schema": {
        "properties": {
          "currency": {
            "type": "string"
          },
          "price": {
            "type": "number"
          }
        },
        "required": [
          "price",
          "currency"
        ],
        "type": "object"
      },
      "prompt": null
    },
    "location": "DE",
    "device": "desktop",
    "run_js": null
  },
  "metadata": {
    "timestamp": 1790854381,
    "request_id": "7511387695155825665"
  }
}
```

{% endcode %}

{% hint style="info" %}
请求 `output` 参数是列表。您可以请求 `output: ["json", "markdown"]` 在单次请求中同时获取提取字段和全文。未请求的格式键返回 `null`.
{% endhint %}

### 代码示例

{% tabs %}
{% tab title="Python（基于模式）" %}

```python
import os
import json
import requests

API_URL = "https://webapi.oxylabs.io/v1/scrape"
HEADERS = {
    "Authorization": f"Bearer ${os.environ['OXYLABS_WEB_API_KEY']}",
    "Content-Type": "application/json"
}

extraction_schema = {
    "type": "object",
    "properties": {
        "headline": {"type": "string"},
        "author": {"type": "string", "nullable": True},
        "publish_date": {
            "type": "string", 
            "description": "ISO 8601 格式的发布日期字符串（YYYY-MM-DD）。"
        },
        "word_count": {"type": "integer"}
    },
    "required": ["headline", "publish_date"]
}

payload = {
    "url": "https://example.com/blog/article-1",
    "output": ["json"],
    "json": {
        "schema": extraction_schema
    }
}

response = requests.post(API_URL, headers=HEADERS, json=payload, timeout=120)
response.raise_for_status()

parsed_data = response.json()["results"][0]["json"]
print(json.dumps(parsed_data, indent=2))
```

{% endtab %}

{% tab title="Node.js（基于提示）" %}

```javascript
const API_URL = "https://webapi.oxylabs.io/v1/scrape";
const HEADERS = {
  "Authorization": `Bearer ${process.env.OXYLABS_WEB_API_KEY}`,
  "Content-Type": "application/json"
};

const payload = {
  url: "https://example.com/product/10928",
  output: ["json"],
  json: {
    prompt: "提取商品标题、满分 5 星的评分、评论数量和主要特性。"
  }
};

async function executeAiExtraction() {
  const response = await fetch(API_URL, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify(payload)
  });

  if (!response.ok) {
    throw new Error(`HTTP Error ${response.status}: ${await response.text()}`);
  }

  const data = await response.json();
  const extractedJson = data.results[0].json;
  console.log("Extracted Data:", JSON.stringify(extractedJson, null, 2));
}

executeAiExtraction();
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.oxylabs.io/products/cn/web-api/scrape/ai-jie-xi.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
