Google Apps Script中用UrlFetchApp登录FinBox失败,响应码400求助
解决Google Apps Script登录FinBox返回400的问题
以下是关键问题点及修正方案:
1. Payload未正确序列化为JSON字符串
当contentType设为application/json时,UrlFetchApp要求payload必须是JSON格式的字符串,而非JavaScript对象。直接传入对象会导致请求格式错误,触发400响应。
2. 响应码判断逻辑颠倒
你代码中把200判定为登录失败、302判定为成功,这与HTTP状态码含义相反:200表示请求成功,302是临时重定向(通常登录成功后会触发跳转)。
3. 缺少必要请求头与会话标识
FinBox的API可能会验证请求的User-Agent,或要求携带登录页面的会话Cookie(部分网站会在此步骤生成CSRF令牌或会话标识),缺少这些信息会被接口拒绝。
修正后的完整代码
function testFinBoxWithCredentials(stock = "AAPL") { // 先请求登录页面获取会话Cookie const loginPageResponse = UrlFetchApp.fetch("https://finbox.com/login/email", { muteHttpExceptions: true, followRedirects: false }); const loginCookies = loginPageResponse.getAllHeaders()['Set-Cookie'] || []; const cookieHeader = loginCookies.map(c => c.split(';')[0]).join('; '); var options = { method: 'post', contentType: 'application/json', // 将payload序列化为JSON字符串 payload: JSON.stringify({ email: 'xxxxxxxxx', password: 'xxxxxxxxx' }), 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', 'Cookie': cookieHeader }, muteHttpExceptions: true, followRedirects: false }; const response = UrlFetchApp.fetch("https://finbox.com/_/api/v5/tokens", options); Logger.log("响应码: " + response.getResponseCode()); if (response.getResponseCode() === 200) { Logger.log("登录成功"); const responseData = JSON.parse(response.getContentText()); Logger.log("返回数据: " + JSON.stringify(responseData)); // 合并登录前后的Cookie const authCookies = response.getAllHeaders()['Set-Cookie'] || []; const fullCookie = [...loginCookies, ...authCookies].map(c => c.split(';')[0]).join('; '); // 访问目标股票页面 const url2 = `https://finbox.com/NASDAQGS:${stock}`; const options2 = { method: "get", headers: { "Cookie": fullCookie, '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 response2 = UrlFetchApp.fetch(url2, options2); Logger.log("目标页面响应码: " + response2.getResponseCode()); Logger.log("目标页面内容: " + response2.getContentText()); } else { Logger.log("登录失败,响应内容: " + response.getContentText()); } }
额外排查建议
如果仍返回400,优先查看response.getContentText()的具体错误信息,FinBox的API通常会明确返回拒绝原因(比如缺少参数、凭证错误等),帮助进一步定位问题。同时请遵守FinBox的服务条款,避免自动化脚本滥用平台资源。
内容的提问来源于stack exchange,提问作者dotNetD
相关产品推荐
相关产品推荐

