【问题标题】:Why is UrlFetchApp unable to fetch content in this case?为什么在这种情况下 UrlFetchApp 无法获取内容?
【发布时间】:2021-07-05 10:17:13
【问题描述】:

我希望将一些文件保存到我的 Google Drive。但是UrlFetchApp.fetch 不会得到任何响应并且会超时。我怎么知道这里出了什么问题?

var url = 'https://www.cmegroup.com/CmeWS/exp/voiProductsViewExport.ctl?media=xls&tradeDate=20210702&assetClassId=2&reportType=F&excluded=CEE,CEU,KCB';
var response = UrlFetchApp.fetch(url);

Logger.log(response.getResponseCode())

var folder = DriveApp.getFolderById(folderID); // omitting folderID in this snippet
var file = folder.createFile(response.getBlob());
file.setName('file.xls');

【问题讨论】:

  • @Argyll 你是怎么做到的?
  • @iansedano:还在思考。我可能会在您的答案中使用该工具和本地触发的脚本在浏览器中打开/关闭它。还想知道是否有其他人发现 CME 的网站有所不同。

标签: google-apps-script urlfetch


【解决方案1】:

听起来 CME 可能阻止了 Apps 脚本。

我今天看到了几个这样的问题。

对于 CME 阻塞(如果是这种情况),您无能为力,但有一种方法可以解决此问题,即使它需要访问浏览器。我注意到如果我使用 JavaScript fetch API,它会正确返回 XLS blob,所以这里有一个使用 Apps Script Web App 的解决方法。

索引.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    
  </body>

  <script>
    const r = fetch('https://www.cmegroup.com/CmeWS/exp/voiProductsViewExport.ctl?media=xls&tradeDate=20210702&assetClassId=2&reportType=F&excluded=CEE,CEU,KCB')
    .then(r => r.blob())
    .then(b => readFile(b))
    .then(result => saveToDrive(result))

    function saveToDrive(base64) {
      google.script.run
        .withSuccessHandler(() => console.log("success"))
        .saveAsXLS(base64)
    }

    function readFile(blob){
      return new Promise((resolve, reject) => {
        var fr = new FileReader();  
        fr.onload = () => {
          resolve(fr.result)
        };
        fr.onerror = reject;
        fr.readAsDataURL(blob);
      });
    }

  </script>

</html>

代码.gs

function doGet(){
  return HtmlService.createHtmlOutputFromFile("index")
}

function saveAsXLS(dataURL){
  const parts = dataURL.split(",")
  const type = (parts[0]).replace('data:','');
  const blob = Utilities.newBlob(Utilities.base64Decode(parts[1], Utilities.Charset.UTF_8), type, "sheet.xls")

  DriveApp.createFile(blob)
}

基本上,它不使用 UrlFetchApp,而是使用浏览器实例来使用 JavaScript fetch API 获取 blob,然后对其进行编码,然后将其发送到 Apps 脚本端。然后,Apps 脚本端对其进行解码并将其保存到云端硬盘。

警告

尽管此时您可能还不如使用curl 或 Python,因为您必须实际访问 Web 应用程序才能执行它。

参考

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多