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

修复Yahoo Finance导入Google Sheets脚本未授权错误并实现每小时更新

解决Yahoo Finance数据导入Google Sheets的未授权错误并实现定时更新

问题描述

原本用于将Yahoo Finance的WTI原油数据(格式:Date | Open | High | Low | Close | Adj Close | Volume)导入Google Sheets的脚本,仅正常运行一天后,执行时返回未授权错误:

{"finance":{"result":null,"error":{"code":"unauthorized","description":"User is not logged in"}}}

需要修复该错误,并实现每小时自动下载数据的功能。

错误原因

Yahoo Finance的公开数据接口现在会校验请求的用户代理(User-Agent)等请求头信息,直接使用UrlFetchApp.fetch()发起无标识请求会被判定为未登录状态,从而触发未授权拦截。

修复后的脚本

以下是修复了未授权问题,并优化了逻辑的完整脚本:

function importYahooFinanceData() {
  const targetSheetName = "WTI_Price_calc";
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheetName);
  
  // 目标工作表不存在则终止执行
  if (!sheet) {
    console.log(`未找到名为${targetSheetName}的工作表`);
    return;
  }

  // Yahoo Finance数据请求URL(WTI原油期货:CL=F)
  const url = "https://query1.finance.yahoo.com/v7/finance/download/CL%3DF?period1=0&period2=9999999999&interval=1d&events=history";
  
  try {
    // 添加模拟浏览器的请求头,绕过未授权校验
    const options = {
      headers: {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
      },
      muteHttpExceptions: true
    };
    
    const response = UrlFetchApp.fetch(url, options);
    const responseCode = response.getResponseCode();
    
    // 校验请求是否成功
    if (responseCode !== 200) {
      console.log(`请求失败,响应码:${responseCode},响应内容:${response.getContentText()}`);
      return;
    }

    const csvData = Utilities.parseCsv(response.getContentText());
    if (csvData.length <= 1) {
      console.log("未获取到有效数据");
      return;
    }

    // 筛选最近365天的数据
    const today = new Date();
    const past365Days = new Date(today);
    past365Days.setDate(today.getDate() - 365);
    
    const filteredData = csvData.slice(1).filter(row => {
      const rowDate = new Date(row[0]);
      return rowDate >= past365Days && row.every(cell => cell !== "null" && cell !== "");
    });

    // 按日期从新到旧排序
    filteredData.sort((a, b) => new Date(b[0]) - new Date(a[0]));

    // 清空原有数据(仅A-G列)
    const lastRow = sheet.getLastRow();
    if (lastRow >= 2) {
      sheet.getRange(2, 1, lastRow - 1, 7).clearContent();
    }

    // 写入新数据
    if (filteredData.length > 0) {
      sheet.getRange(2, 1, filteredData.length, filteredData[0].length).setValues(filteredData);
      console.log(`成功更新${filteredData.length}条数据`);
    } else {
      console.log("无符合条件的数据可更新");
    }
  } catch (error) {
    console.log(`脚本执行出错:${error.message}`);
  }
}

关键修改点

  • 添加了User-Agent请求头,模拟浏览器请求,绕过Yahoo的未授权校验
  • 优化了工作表获取逻辑,直接通过名称查找而非依赖当前激活工作表
  • 增加了请求异常处理和响应码校验,便于排查问题
  • 移除了原脚本中重复定义的url和response变量
  • 优化了数据过滤条件,排除空单元格数据

实现每小时自动更新

通过Google Apps Script的触发器功能设置定时执行:

  • 打开Google Sheets对应的脚本编辑器(工具 > 脚本编辑器)
  • 点击左侧菜单栏的「触发器」图标(时钟形状)
  • 点击「添加触发器」按钮
  • 在配置面板中设置:
    • 选择要运行的函数:importYahooFinanceData
    • 选择部署类型:「头部部署」
    • 选择事件源:「时间驱动」
    • 选择时间类型:「小时计时器」
    • 选择小时间隔:「每小时」
  • 点击「保存」,完成定时触发器配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:20:56