You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Langchain Recursive URL Loader爬取Next.js文档页数不一致问题

问题:Recursive URL Loader爬取Next.js文档时页面数量不稳定

使用Langchain的RecursiveUrlLoader爬取Next.js官方文档,预期每次爬取的页面数量保持一致,但实际每次运行后获取的页面数量均不相同。

实现代码

import { RecursiveUrlLoader } from 'langchain/document_loaders/web/recursive_url';
import { compile } from 'html-to-text';

export const handleScrape = async (req, res) => {
  const { title, url } = req.body; // 从请求体中提取标题和URL

  const compiledConvert = compile({ wordwrap: 130 }); // 返回(text: string) => string;

  // if (!url) {
  //   res.status(400).send('No url provided');
  //   return;
  // }

  const loader = new RecursiveUrlLoader(url, {
    extractor: compiledConvert,
    maxDepth: 50, // 根据需要调整
  });

  const docs = await loader.load();
  console.log(`从${title}爬取了${docs.length}个文档`);

  res.send(docs);
};

现象

多次执行爬取任务,返回的文档数量存在明显差异(例如某次抓取到123个页面,另一次仅抓取到118个)。


原因分析与解决方案

1. 动态内容渲染导致链接抓取不全

Next.js文档部分页面采用客户端动态渲染,RecursiveUrlLoader默认基于静态HTML解析链接,动态生成的链接可能因加载时机不同,每次爬取时抓取到的数量不一致。

  • 解决办法:改用支持动态渲染的加载方案,比如结合PuppeteerLoader来渲染完整页面后再解析链接;或者自定义extractor函数,确保能捕获动态生成的URL。

2. 目标站点反爬机制拦截请求

Next.js官方文档可能存在临时请求限制,多次快速爬取时部分请求被拦截,导致页面未成功抓取。

  • 解决办法:在loader配置中添加请求延迟,同时配置请求头模拟浏览器:
    const loader = new RecursiveUrlLoader(url, {
      extractor: compiledConvert,
      maxDepth: 50,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
      },
      delay: 1000 // 每次请求间隔1秒
    });
    

3. 默认链接去重逻辑存在漏洞

RecursiveUrlLoader的默认去重可能未处理URL格式差异(如带锚点、不同顺序的查询参数),导致同一页面被重复计数或漏记。

  • 解决办法:自定义getUrls方法,手动实现严格的URL标准化和去重:
    const cheerio = require('cheerio'); // 需提前安装cheerio
    
    const loader = new RecursiveUrlLoader(url, {
      extractor: compiledConvert,
      maxDepth: 50,
      getUrls: async (html, baseUrl) => {
        const $ = cheerio.load(html);
        const urls = [];
        $('a').each((i, el) => {
          let href = $(el).attr('href');
          if (href) {
            // 标准化URL:去除锚点、统一查询参数顺序
            const parsedUrl = new URL(href, baseUrl);
            parsedUrl.hash = '';
            const params = new URLSearchParams(parsedUrl.search);
            parsedUrl.search = Array.from(params.entries()).sort().map(([k, v]) => `${k}=${v}`).join('&');
            urls.push(parsedUrl.toString());
          }
        });
        // 去重
        return [...new Set(urls)];
      }
    });
    

4. 网络波动导致请求失败

爬取过程中网络不稳定,部分请求超时或失败,未被计入最终结果。

  • 解决办法:添加请求重试机制,可通过包装loader的请求逻辑,或使用支持重试的HTTP客户端替代默认请求方式。

内容的提问来源于stack exchange,提问作者Olamide Onabiyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:40:14