> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olostep.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Olostep NodeJS SDK

> 官方 NodeJS SDK，用于从网络搜索、提取和结构化数据

**NPM 包**: [olostep](https://www.npmjs.com/package/olostep)

## 入门

```bash theme={null}
npm install olostep
```

<CodeGroup>
  ```ts camelCase theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({apiKey: process.env.OLOSTEP_API_KEY});

  // 最小化抓取示例
  const result = await client.scrapes.create('https://example.com');
  console.log(result.id, result.html_content);
  ```

  ```ts snake_case theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({api_key: process.env.OLOSTEP_API_KEY});

  // 最小化抓取示例
  const result = await client.scrapes.create('https://example.com');
  console.log(result.id, result.html_content);
  ```
</CodeGroup>

<Note>
  NodeJS SDK 接受所有参数的 **camelCase** 和 **snake\_case**。如果你是为 AI 代理构建，请使用 **snake\_case**，它与 API 的原生字段名称匹配。
</Note>

## 用法

### 抓取

使用各种选项抓取单个 URL：

<CodeGroup>
  ```ts camelCase theme={null}
  import Olostep, {Format} from 'olostep';

  const client = new Olostep({apiKey: 'your_api_key'});

  // 简单抓取
  const scrape = await client.scrapes.create('https://example.com');

  // 使用多种格式
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    formats: [Format.HTML, Format.MARKDOWN, Format.TEXT],
    waitBeforeScraping: 1000,
    removeImages: true
  });

  // 访问内容
  console.log(scrape.html_content);
  console.log(scrape.markdown_content);

  // 通过 ID 获取抓取
  const fetched = await client.scrapes.get(scrape.id);
  ```

  ```ts snake_case theme={null}
  import Olostep, {Format} from 'olostep';

  const client = new Olostep({api_key: 'your_api_key'});

  // 简单抓取
  const scrape = await client.scrapes.create('https://example.com');

  // 使用多种格式
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    formats: [Format.HTML, Format.MARKDOWN, Format.TEXT],
    wait_before_scraping: 1000,
    remove_images: true
  });

  // 访问内容
  console.log(scrape.html_content);
  console.log(scrape.markdown_content);

  // 通过 ID 获取抓取
  const fetched = await client.scrapes.get(scrape.id);
  ```
</CodeGroup>

### 批量处理

在一个批次中处理多个 URL：

<CodeGroup>
  ```ts camelCase theme={null}
  // 使用 URL 字符串（自动生成自定义 ID）
  const batch = await client.batches.create([
    'https://example.com',
    'https://example.org',
    'https://example.net'
  ]);

  // 或使用显式自定义 ID
  const batch = await client.batches.create([
    {url: 'https://example.com', customId: 'site-1'},
    {url: 'https://example.org', customId: 'site-2'}
  ]);

  console.log(`批次 ${batch.id} 已创建，包含 ${batch.total_urls} 个 URL`);

  // 等待完成
  await batch.waitTillDone({
    checkEveryNSecs: 5,
    timeoutSeconds: 120
  });

  // 获取批次信息
  const info = await batch.info();
  console.log(info);

  // 流式处理单个结果
  for await (const item of batch.items()) {
    console.log(item.custom_id);
  }
  ```

  ```ts snake_case theme={null}
  // 使用 URL 字符串（自动生成自定义 ID）
  const batch = await client.batches.create([
    'https://example.com',
    'https://example.org',
    'https://example.net'
  ]);

  // 或使用显式自定义 ID
  const batch = await client.batches.create([
    {url: 'https://example.com', custom_id: 'site-1'},
    {url: 'https://example.org', custom_id: 'site-2'}
  ]);

  console.log(`批次 ${batch.id} 已创建，包含 ${batch.total_urls} 个 URL`);

  // 等待完成
  await batch.waitTillDone({
    check_every_n_secs: 5,
    timeout_seconds: 120
  });

  // 获取批次信息
  const info = await batch.info();
  console.log(info);

  // 流式处理单个结果
  for await (const item of batch.items()) {
    console.log(item.custom_id);
  }
  ```
</CodeGroup>

### 爬取

爬取整个网站：

<CodeGroup>
  ```ts camelCase theme={null}
  const crawl = await client.crawls.create({
    url: 'https://example.com',
    maxPages: 100,
    maxDepth: 3,
    includeUrls: ['*/blog/*'],
    excludeUrls: ['*/admin/*']
  });

  console.log(`爬取 ${crawl.id} 已启动`);

  // 等待完成
  await crawl.waitTillDone({
    checkEveryNSecs: 10,
    timeoutSeconds: 300
  });

  // 获取爬取信息
  const info = await crawl.info();
  console.log(`已爬取 ${info.pages_crawled} 页`);

  // 流式处理爬取的页面
  for await (const page of crawl.pages()) {
    console.log(page.url, page.status_code);
  }
  ```

  ```ts snake_case theme={null}
  const crawl = await client.crawls.create({
    url: 'https://example.com',
    max_pages: 100,
    max_depth: 3,
    include_urls: ['*/blog/*'],
    exclude_urls: ['*/admin/*']
  });

  console.log(`爬取 ${crawl.id} 已启动`);

  // 等待完成
  await crawl.waitTillDone({
    check_every_n_secs: 10,
    timeout_seconds: 300
  });

  // 获取爬取信息
  const info = await crawl.info();
  console.log(`已爬取 ${info.pages_crawled} 页`);

  // 流式处理爬取的页面
  for await (const page of crawl.pages()) {
    console.log(page.url, page.status_code);
  }
  ```
</CodeGroup>

### 网站映射

从网站生成 URL 的站点地图：

<CodeGroup>
  ```ts camelCase theme={null}
  const map = await client.maps.create({
    url: 'https://example.com',
    topN: 100,
    includeSubdomain: true,
    searchQuery: 'blog posts'
  });

  console.log(`地图 ${map.id} 已创建`);

  // 流式处理 URL
  for await (const url of map.urls()) {
    console.log(url);
  }

  // 获取地图信息
  const info = await map.info();
  ```

  ```ts snake_case theme={null}
  const map = await client.maps.create({
    url: 'https://example.com',
    top_n: 100,
    include_subdomain: true,
    search_query: 'blog posts'
  });

  console.log(`地图 ${map.id} 已创建`);

  // 流式处理 URL
  for await (const url of map.urls()) {
    console.log(url);
  }

  // 获取地图信息
  const info = await map.info();
  ```
</CodeGroup>

### AI 驱动的答案

使用 AI 从网页获取答案：

<CodeGroup>
  ```ts camelCase theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({apiKey: 'your_api_key'});

  // 简单任务：直接传递字符串
  const answer = await client.answers.create(
    'What is the main topic of https://example.com?'
  );
  console.log(answer.answer);
  console.log(answer.sources);

  // 使用结构化 JSON 输出
  const structured = await client.answers.create({
    task: 'Extract all product names and prices from https://example.com',
    jsonFormat: {
      products: [{name: '', price: ''}]
    }
  });
  console.log(structured.json_content);

  // 通过 ID 检索先前创建的答案
  const fetched = await client.answers.get(answer.id);
  console.log(fetched.answer);
  ```

  ```ts snake_case theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({api_key: 'your_api_key'});

  // 简单任务：直接传递字符串
  const answer = await client.answers.create(
    'What is the main topic of https://example.com?'
  );
  console.log(answer.answer);
  console.log(answer.sources);

  // 使用结构化 JSON 输出
  const structured = await client.answers.create({
    task: 'Extract all product names and prices from https://example.com',
    json_format: {
      products: [{name: '', price: ''}]
    }
  });
  console.log(structured.json_content);

  // 通过 ID 检索先前创建的答案
  const fetched = await client.answers.get(answer.id);
  console.log(fetched.answer);
  ```
</CodeGroup>

### 内容检索

检索先前抓取的内容：

```ts theme={null}
// 获取特定格式的内容
const content = await client.retrieve(retrieveId, Format.MARKDOWN);
console.log(content.markdown_content);

// 多种格式
const content = await client.retrieve(retrieveId, [
  Format.HTML,
  Format.MARKDOWN
]);
```

### 高级选项

#### 自定义操作

在抓取前执行浏览器操作：

```ts theme={null}
const scrape = await client.scrapes.create({
  url: 'https://example.com',
  actions: [
    {type: 'wait', milliseconds: 2000},
    {type: 'click', selector: '#load-more'},
    {type: 'scroll', distance: 1000},
    {type: 'fill_input', selector: '#search', value: 'query'}
  ]
});
```

#### 地理位置

使用预定义的国家代码或任何有效的国家代码字符串从不同国家抓取：

<CodeGroup>
  ```ts camelCase theme={null}
  import Olostep, {Country} from 'olostep';

  const client = new Olostep({apiKey: 'your_api_key'});

  // 使用预定义的枚举值（US, DE, FR, GB, SG）
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    country: Country.DE  // 德国
  });

  // 或使用任何有效的国家代码作为字符串
  const scrape2 = await client.scrapes.create({
    url: 'https://example.com',
    country: 'jp'  // 日本
  });
  ```

  ```ts snake_case theme={null}
  import Olostep, {Country} from 'olostep';

  const client = new Olostep({api_key: 'your_api_key'});

  // 使用预定义的枚举值（US, DE, FR, GB, SG）
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    country: Country.DE  // 德国
  });

  // 或使用任何有效的国家代码作为字符串
  const scrape2 = await client.scrapes.create({
    url: 'https://example.com',
    country: 'jp'  // 日本
  });
  ```
</CodeGroup>

#### 缓存

默认情况下，每个抓取请求都会获取最新页面（`max_age: 0`）。传递 `maxAge` 以重用具有相同参数的最近结果并提高响应时间。值为 **秒**；最大为 7 天（`604800`）。详情见 [缓存](/features/scrapes#caching)。

<CodeGroup>
  ```ts camelCase theme={null}
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    formats: ['markdown'],
    maxAge: 86400 // 接受最多 1 天前的结果
  });
  ```

  ```ts snake_case theme={null}
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    formats: ['markdown'],
    max_age: 86400 // 接受最多 1 天前的结果
  });
  ```
</CodeGroup>

#### LLM 提取

使用 LLM 提取结构化数据：

<CodeGroup>
  ```ts camelCase theme={null}
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    llmExtract: {
      schema: {
        title: 'string',
        price: 'number',
        description: 'string'
      },
      prompt: '从此页面提取产品信息'
    }
  });
  ```

  ```ts snake_case theme={null}
  const scrape = await client.scrapes.create({
    url: 'https://example.com',
    llm_extract: {
      schema: {
        title: 'string',
        price: 'number',
        description: 'string'
      },
      prompt: '从此页面提取产品信息'
    }
  });
  ```
</CodeGroup>

### 客户端配置

<CodeGroup>
  ```ts camelCase theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({
    apiKey: 'your_api_key',
    apiBaseUrl: 'https://api.olostep.com/v1',  // 可选
    timeoutMs: 150000,  // 150 秒（可选）
    retry: {
      maxRetries: 3,
      initialDelayMs: 1000
    },
    userAgent: 'MyApp/1.0'  // 可选
  });
  ```

  ```ts snake_case theme={null}
  import Olostep from 'olostep';

  const client = new Olostep({
    api_key: 'your_api_key',
    api_base_url: 'https://api.olostep.com/v1',  // 可选
    timeout_ms: 150000,  // 150 秒（可选）
    retry: {
      max_retries: 3,
      initial_delay_ms: 1000
    },
    user_agent: 'MyApp/1.0'  // 可选
  });
  ```
</CodeGroup>

### 功能亮点

* 以异步为主的客户端，全面支持 TypeScript。
* 使用 TypeScript 枚举和接口（格式、国家、操作等）进行类型安全输入。
* 丰富的资源命名空间，提供简写调用（`client.scrapes.create()`）和显式方法（`client.scrapes.get()`）。
* 共享传输层，支持重试、超时和 JSON 解码。
* 全面的错误层次结构。
