Skip to main content
本指南展示如何将 Apify 与 LangChain 结合使用,从 Apify 数据集中加载文档。

概述

Apify 是一个用于网络爬虫和数据提取的云平台,它提供了一个包含超过 10,000 个现成应用程序(称为 Actors)的生态系统,适用于各种网络爬虫、抓取和数据提取用例。 本指南展示如何从 Apify 数据集 加载文档:这是一种可扩展的仅追加存储,专为存储结构化的网络抓取结果(例如产品列表或 Google 搜索结果页面)而设计,然后可以将它们导出为 JSON、CSV 或 Excel 等多种格式。 数据集通常用于保存不同 Actors 的结果。例如:
  • 网站内容爬虫 Actor 深度抓取网站(如文档、知识库、帮助中心或博客),并将网页的文本内容存储到数据集中
  • RAG 网络浏览器 Actor 查询 Google 搜索,抓取结果中的前 N 个页面,并以 Markdown 格式返回清理后的内容,供大型语言模型进一步处理

集成详情

加载器特性

来源文档惰性加载原生异步支持
Apify 数据集

设置

凭证

您需要注册一个 Apify 账户 并获取您的 Apify API 令牌。将其设置为环境变量:
process.env.APIFY_TOKEN = "your-apify-token"

安装

您首先需要安装官方的 Apify 客户端和 LangChain 包:
npm
npm install apify-client @langchain/community @langchain/core @langchain/openai hnswlib-node
有关安装 LangChain 包的一般说明,请参阅此部分

定价

许多 Actors 支持按事件付费 (PPE) 定价,您需要为 Actor 作者定义的明确事件(例如,每个数据集项)付费。 这可能非常适合代理工作负载,因为您希望获得清晰、按操作计算的成本。 Apify 还提供按使用量付费的定价,并提供免费套餐。 定价因 Actor 而异——有些 Actors 是免费的(您只需支付平台使用费),而其他 Actors 则按结果或事件收费。详情请参阅 Apify 定价

使用

从新数据集(抓取网站并将数据存储在 Apify 数据集中)

如果您在 Apify 平台上还没有现有的数据集,则需要通过调用一个 Actor 并等待结果来初始化文档加载器。 在下面的示例中,我们使用 网站内容爬虫 Actor 来抓取 LangChain 文档,将结果存储在 Apify 数据集中,然后使用 ApifyDatasetLoader 加载该数据集。 为了演示,我们将使用快速的 Cheerio 爬虫类型,并将抓取的页面数量限制为 10。 注意: 运行网站内容爬虫可能需要一些时间,具体取决于网站的大小。对于大型网站,可能需要几个小时甚至几天! 示例如下:
import { ApifyDatasetLoader } from "@langchain/community/document_loaders/web/apify_dataset";
import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai";
import { Document } from "@langchain/core/documents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { createStuffDocumentsChain } from "@langchain/classic/chains/combine_documents";
import { createRetrievalChain } from "@langchain/classic/chains/retrieval";

const APIFY_TOKEN = "YOUR-APIFY-TOKEN"; // 或设置为 process.env.APIFY_TOKEN
const OPENAI_API_KEY = "YOUR-OPENAI-API-KEY"; // 或设置为 process.env.OPENAI_API_KEY

/*
 * datasetMappingFunction 是一个将您的 Apify 数据集格式映射到 LangChain 文档的函数。
 * 在下面的示例中,Apify 数据集格式如下所示:
 * {
 *   "url": "https://apify.com",
 *   "text": "Apify is the best web scraping and automation platform."
 * }
 */
const loader = await ApifyDatasetLoader.fromActorCall(
  "apify/website-content-crawler",
  {
    maxCrawlPages: 10,
    crawlerType: "cheerio",
    startUrls: [{ url: "https://js.langchain.com/docs/" }],
  },
  {
    datasetMappingFunction: (item) =>
      new Document({
        pageContent: (item.text || "") as string,
        metadata: { source: item.url },
      }),
    clientOptions: {
      token: APIFY_TOKEN,
    },
  }
);

const docs = await loader.load();

const vectorStore = await HNSWLib.fromDocuments(
  docs,
  new OpenAIEmbeddings({ apiKey: OPENAI_API_KEY })
);

const model = new ChatOpenAI({
  model: "gpt-5-mini",
  temperature: 0,
  apiKey: OPENAI_API_KEY,
});

const questionAnsweringPrompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    "根据以下上下文回答用户的问题:\n\n{context}",
  ],
  ["human", "{input}"],
]);

const combineDocsChain = await createStuffDocumentsChain({
  llm: model,
  prompt: questionAnsweringPrompt,
});

const chain = await createRetrievalChain({
  retriever: vectorStore.asRetriever(),
  combineDocsChain,
});

const res = await chain.invoke({ input: "什么是 LangChain?" });

console.log(res.answer);
console.log(res.context.map((doc) => doc.metadata.source));

/*
  LangChain 是一个用于开发由语言模型驱动的应用程序的框架。
  [
    'https://js.langchain.com/docs/',
    'https://js.langchain.com/docs/modules/chains/',
    'https://js.langchain.com/docs/modules/chains/llmchain/',
    'https://js.langchain.com/docs/category/functions-4'
  ]
*/

何时使用 Apify

Apify 在以下情况下非常理想:
  • 需要访问数千个预构建的 Actors,适用于各种平台(社交媒体、电子商务、搜索引擎等)
  • 需要超出简单搜索的自定义网络抓取和自动化工作流
  • 灵活的 Actor 生态系统:可以运行 Apify Store 中的任何 Actor

从现有数据集

如果您已经运行了一个 Actor 并且在 Apify 平台上有一个现有的数据集,您可以直接使用构造函数初始化文档加载器
import { ApifyDatasetLoader } from "@langchain/community/document_loaders/web/apify_dataset";
import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai";
import { Document } from "@langchain/core/documents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { createRetrievalChain } from "@langchain/classic/chains/retrieval";
import { createStuffDocumentsChain } from "@langchain/classic/chains/combine_documents";

const APIFY_TOKEN = "YOUR-APIFY-TOKEN"; // 或设置为 process.env.APIFY_TOKEN
const OPENAI_API_KEY = "YOUR-OPENAI-API-KEY"; // 或设置为 process.env.OPENAI_API_KEY

/*
 * datasetMappingFunction 是一个将您的 Apify 数据集格式映射到 LangChain 文档的函数。
 * 在下面的示例中,Apify 数据集格式如下所示:
 * {
 *   "url": "https://apify.com",
 *   "text": "Apify is the best web scraping and automation platform."
 * }
 */
const loader = new ApifyDatasetLoader("your-dataset-id", {
  datasetMappingFunction: (item) =>
    new Document({
      pageContent: (item.text || "") as string,
      metadata: { source: item.url },
    }),
  clientOptions: {
    token: APIFY_TOKEN,
  },
});

const docs = await loader.load();

const vectorStore = await HNSWLib.fromDocuments(
  docs,
  new OpenAIEmbeddings({ apiKey: OPENAI_API_KEY })
);

const model = new ChatOpenAI({
  model: "gpt-5-mini",
  temperature: 0,
  apiKey: OPENAI_API_KEY,
});

const questionAnsweringPrompt = ChatPromptTemplate.fromMessages([
  [
    "system",
    "根据以下上下文回答用户的问题:\n\n{context}",
  ],
  ["human", "{input}"],
]);

const combineDocsChain = await createStuffDocumentsChain({
  llm: model,
  prompt: questionAnsweringPrompt,
});

const chain = await createRetrievalChain({
  retriever: vectorStore.asRetriever(),
  combineDocsChain,
});

const res = await chain.invoke({ input: "什么是 LangChain?" });

console.log(res.answer);
console.log(res.context.map((doc) => doc.metadata.source));

/*
  LangChain 是一个用于开发由语言模型驱动的应用程序的框架。
  [
    'https://js.langchain.com/docs/',
    'https://js.langchain.com/docs/modules/chains/',
    'https://js.langchain.com/docs/modules/chains/llmchain/',
    'https://js.langchain.com/docs/category/functions-4'
  ]
*/

其他 Actor 示例

Apify Store 包含数千个预构建的 Actors。以下是您可以使用文档加载器的其他流行 Actors 示例:

Instagram 抓取器

import { ApifyDatasetLoader } from "@langchain/community/document_loaders/web/apify_dataset";
import { Document } from "@langchain/core/documents";

const docs = await ApifyDatasetLoader.fromActorCall(
  "apify/instagram-scraper",
  {
    directUrls: ["https://www.instagram.com/p/ABC123/"],
    resultsType: "posts",
    resultsLimit: 10,
  },
  {
    datasetMappingFunction: (item) =>
      new Document({
        pageContent: item.caption || "",
        metadata: {
          source: item.url,
          likesCount: item.likesCount,
          commentsCount: item.commentsCount,
        },
      }),
    clientOptions: { token: process.env.APIFY_TOKEN },
  }
);

Google 搜索结果抓取器

import { ApifyDatasetLoader } from "@langchain/community/document_loaders/web/apify_dataset";
import { Document } from "@langchain/core/documents";

const searchDocs = await ApifyDatasetLoader.fromActorCall(
  "apify/google-search-scraper",
  {
    queries: "langchain javascript tutorial",
    maxPagesPerQuery: 1,
    countryCode: "us",
    languageCode: "en",
  },
  {
    datasetMappingFunction: (item) => {
      const organicResults = Array.isArray(item.organicResults)
        ? item.organicResults
        : [];

      const pageContent = organicResults
        .map(
          (r) =>
            `${r.position}. ${r.title}\n${r.url}\n${r.description ?? ""}`.trim()
        )
        .join("\n\n");

      return new Document({
        pageContent,
        metadata: {
          source: item.searchQuery?.url ?? item.url,
          query: item.searchQuery?.term,
          page: item.searchQuery?.page,
        },
      });
    },
    clientOptions: { token: process.env.APIFY_TOKEN },
  }
);
浏览 Apify Store 以发现更多适合您用例的 Actors。

使用 Apify MCP 服务器

不确定使用哪个 Actor 或其需要哪些参数? Apify MCP(模型上下文协议)服务器 可以帮助您发现可用的 Actors、探索其输入模式并了解参数要求。 通过 HTTP 连接到 Apify MCP 服务器时,请在请求头中包含您的 Apify 令牌:
Authorization: Bearer <APIFY_TOKEN>
更多信息,请参阅 LangChain MCP 文档Apify MCP 服务器