修复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
相关产品推荐
相关产品推荐

