【问题标题】:How to pull HTML table data (Yahoo Finance) with Cheerio in Google Apps Script?如何在 Google Apps 脚本中使用 Cheerio 提取 HTML 表格数据(雅虎财经)?
【发布时间】:2026-02-20 03:50:02
【问题描述】:

我正在尝试从https://finance.yahoo.com/quote/CL%3DF/history?p=CL%3DF 获取整个表格数据。在浏览器上,网页默认显示截至 2020 年 10 月 12 日的 1 年数据。但是以下代码由于某种原因没有提取整个表数据。它只提取了部分数据,仅提取了不到 5 个月的数据,直到 2021 年 5 月 20 日。我错过了什么?任何人都可以帮助修复代码中的任何错误吗?谢谢!

function test() {
  const url = 'https://finance.yahoo.com/quote/CL%3DF/history?p=CL%3DF';
  const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
  const $ = Cheerio.load(res);
  // The URL webpage shows one year data down to Oct 12, 2021 on the browser.
  // But the code below got data only down to May 20, 2020.  Why am I mssing?
  var data = $('table').find('td').toArray().map(x => $(x).text());
  console.log(data[data.length-8]);     // Print the last row date other than the web note
}

【问题讨论】:

    标签: google-apps-script web-scraping html-table cheerio


    【解决方案1】:

    当我看到 HTML 数据时,表格选项卡似乎没有所有数据。但幸运的是,我注意到 Javascript 中的对象包含您期望的所有数据。那么下面修改后的脚本呢?

    修改脚本:

    在此修改后的脚本中,使用了电子表格的容器绑定脚本。当然,您可以使用独立类型。但是这种情况,请修改SpreadsheetApp.getActiveSpreadsheet()

    当您使用该脚本时,请将以下修改后的脚本复制粘贴到Spreadsheet的脚本编辑器中并设置工作表名称,然后运行。这样,所有数据都被检索并放入电子表格。

    function test() {
      const url = 'https://finance.yahoo.com/quote/CL%3DF/history?p=CL%3DF';
      const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
      const $ = Cheerio.load(res);
    
      // I modified below script
      const data = $('script').toArray().reduce((ar, x) => {
        const c = $(x).get()[0].children;
        if (c.length > 0) {
          const d = c[0].data.trim().match(/({"context"[\s\S\w]+);\n}\(this\)\);/);
          if (d && d.length == 2) {
            ar.push(JSON.parse(d[1]));
          }
        }
        return ar;
      }, []);
      if (data.length == 0) throw new Error("No data.");
      const header = ["date","open","high","low","close","adjclose","volume"];
      const ar = data[0].context.dispatcher.stores.HistoricalPriceStore.prices.map(o => header.map(h => h == "date" ? new Date(o[h] * 1000) : (o[h] || "")));
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1"); // <--- Please set the sheet name you want to put the values.
      sheet.getRange(1, 1, ar.length, ar[0].length).setValues(ar);
    }
    

    结果:

    上面的脚本运行时,得到如下结果。

    参考资料:

    【讨论】:

    • 抱歉!有用!非常感谢!
    • @Newbie 感谢您的回复。我很高兴你的问题得到了解决。也谢谢你。
    最近更新 更多