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

使用Puppeteer获取会话生成URL对应的PDF缓冲区技术问询

嘿,我来帮你搞定用Puppeteer抓取这个网站PDF的问题!针对这个网站两次请求的逻辑(先拿GUID再取PDF),我们有两种靠谱的实现方式,直接上干货:

方案一:直接模拟两次请求(高效推荐)

这种方式不用折腾页面跳转,直接复刻网站的请求逻辑,速度更快:

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 先访问站点初始化会话(有些网站会校验会话Cookie,这步不能省)
  await page.goto('http://epicdocs.planningni.gov.uk/');

  // 第一步:获取会话GUID
  const targetGuid = await page.evaluate(async () => {
    const res = await fetch('http://epicdocs.planningni.gov.uk/ViewDocument.pa?uri=4157826&ext=PDF');
    const pageContent = await res.text();
    // 用正则匹配页面里的GUID(适配网站返回的HTML结构)
    const guidMatch = pageContent.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
    return guidMatch ? guidMatch[0] : null;
  });

  if (!targetGuid) {
    console.error('糟了,没拿到GUID!');
    await browser.close();
    return;
  }
  console.log('成功拿到GUID:', targetGuid);

  // 第二步:用GUID获取PDF缓冲区
  const pdfBuffer = await page.evaluate(async (guid) => {
    const pdfRes = await fetch(`http://epicdocs.planningni.gov.uk/ViewDocument.aspx?guid=${guid}`);
    if (!pdfRes.ok) throw new Error('获取PDF失败');
    const blob = await pdfRes.blob();
    const arrayBuffer = await blob.arrayBuffer();
    return Buffer.from(arrayBuffer);
  }, targetGuid);

  // 把缓冲区写入本地文件
  fs.writeFileSync('target-document.pdf', pdfBuffer);
  console.log('PDF已保存!');

  await browser.close();
})();
方案二:模拟点击+监听请求(贴近真实操作)

如果你想完全模拟用户点击链接的流程,可以监听新标签页的请求,拦截PDF返回:

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 打开包含文档链接的页面(替换成实际页面地址)
  await page.goto('你要访问的包含文档链接的页面URL');

  // 监听新标签页创建事件
  browser.on('targetcreated', async (target) => {
    if (target.type() === 'page') {
      const newTab = await target.page();
      // 监听新标签页的请求完成事件,捕获PDF请求
      newTab.on('requestfinished', async (request) => {
        const requestUrl = request.url();
        if (requestUrl.includes('ViewDocument.aspx?guid=')) {
          const pdfResponse = await request.response();
          const pdfBuffer = await pdfResponse.buffer();
          // 保存PDF
          fs.writeFileSync('clicked-document.pdf', pdfBuffer);
          console.log('通过点击链接拿到PDF啦!');
          await browser.close();
        }
      });
    }
  });

  // 点击文档链接(替换成实际的元素选择器,比如a[href*="ViewDocument.pa"])
  await page.click('文档链接的CSS选择器');
})();

几个要注意的细节:

  • 一定要先访问站点初始化会话,不然网站可能会拒绝你的请求(Cookie校验)。
  • 如果正则匹配GUID失败,打开第一个请求的返回页面看看,可能需要调整正则或者用DOM解析(比如document.querySelector找包含GUID的元素)。
  • 要是遇到反爬,可以给Puppeteer设置--no-sandbox、添加自定义userAgent,或者在请求之间加个await page.waitForTimeout(1000)延迟一下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:44:00