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

使用Puppeteer/BeautifulSoup/Selenium均无法获取页面中var doc变量的技术求助

Puppeteer/BeautifulSoup/Selenium均无法获取页面中var doc变量的技术求助

首先,我注意到你的代码和场景存在几个关键问题,咱们一步步来解决:


1. 先修复代码中的致命语法错误和缺失步骤

你提供的Puppeteer代码有两个致命问题,这是你拿不到数据的首要原因:

  • 多了一个多余的 });:await page.setViewport({ width: 1280, height: 800 }); }); 这行末尾的额外});会直接导致代码语法报错,程序终止执行。
  • 完全缺失打开目标页面的page.goto()调用:没有访问目标URL,页面都没加载,当然拿不到任何script内容!

先把这两个问题补上和修正,代码才能正常运行。


2. 分析为什么拿不到var doc的深层原因

从你提供的页面源码片段来看,var doc是内联在script标签里的,但还可能存在这些阻碍:

  • 正则匹配能力不足:原正则/var doc = \{[^}]*\};/g只能匹配单行的对象定义,而你的doc内容跨了多行(比如weight字段包含换行和HTML标签),这个正则会提前终止匹配,拿不到完整的对象。
  • 无头浏览器被检测:默认的Puppeteer无头模式会被部分网站识别,导致内容不渲染或script不执行。
  • 等待策略不可靠:固定时长的setTimeout等待,可能页面还没完全加载完成就开始提取内容了。
  • 用BeautifulSoup的局限性:它是静态HTML解析工具,不会执行JavaScript,如果这个script是页面加载后动态注入的,BeautifulSoup根本看不到它。

3. 改进后的Puppeteer解决方案

我整理了修复并优化后的代码,解决了上述所有问题:

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

async function scrapeTezData(keyword = "yapay zeka") {
  let browser;
  try {
    browser = await puppeteer.launch({
      headless: 'new', // 使用新版无头模式,更接近真实浏览器,不易被反爬识别
      args: [
        '--no-sandbox', 
        '--disable-setuid-sandbox',
        '--disable-blink-features=AutomationControlled' // 禁用自动化特征检测
      ]
    });
    const page = await browser.newPage();
    
    // 模拟更真实的浏览器请求头
    await page.setExtraHTTPHeaders({
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
      'Accept-Language': 'tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3',
      'Upgrade-Insecure-Requests': '1'
    });
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
    await page.setViewport({ width: 1280, height: 800 });

    // 关键:替换成你实际要爬取的目标URL
    await page.goto('https://你的目标页面URL.com', { waitUntil: 'networkidle2' });

    console.log("Waiting for all resources to load...");
    // 等待网络空闲3秒,确保所有JS执行完成
    await page.waitForNetworkIdle({ idleTime: 3000 });

    // 提取script中的var doc内容
    const scriptData = await page.evaluate(() => {
      const scripts = Array.from(document.querySelectorAll('script'));
      let docBlocks = [];

      for (const script of scripts) {
        const content = script.innerHTML.trim();
        if (!content) continue;
        
        // 过滤包含目标变量的script
        if (content.includes('var rows = []') && content.includes('var doc =')) {
          // 匹配跨多行的var doc = { ... }; 用[\s\S]*?匹配任意字符(包括换行),非贪婪模式避免过度匹配
          const docRegex = /var doc = \{[\s\S]*?\};/g;
          const matches = content.match(docRegex);
          if (matches) {
            docBlocks.push(...matches);
          }
        }
      }

      return docBlocks;
    });

    console.log('Successfully extracted doc blocks:', scriptData);
    // 保存结果到文件
    if (scriptData.length > 0) {
      await fs.promises.writeFile('tezData.json', JSON.stringify(scriptData, null, 2));
      console.log('Data saved to tezData.json');
    } else {
      console.log('No doc blocks found - please check if the target page has the expected content');
    }

  } catch (error) {
    console.error(`Scraping failed: ${error.message}`);
    console.error('Error stack:', error.stack);
  } finally {
    if (browser) {
      await browser.close();
    }
  }
}

// 调用爬取函数
scrapeTezData();

4. 其他调试建议

  • 把headless改成false,打开浏览器可视化查看页面加载情况,确认页面是否正常显示了你要的内容。
  • 在代码里添加浏览器日志捕获:page.on('console', msg => console.log('Browser log:', msg.text())),这样可以看到page.evaluate里的console.log输出,方便确认script内容是否和你预期一致。
  • 如果用Selenium,也要确保等待页面完全加载,然后提取所有script标签的innerHTML,用同样的正则去匹配内容——不要直接尝试访问window.doc,因为它可能在script的局部作用域里,不是全局变量。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:20:28