为什么 UrlFetchApp 在这种情况下无法获取内容?
Why is UrlFetchApp unable to fetch content in this case?
我希望将一些文件保存到我的 Google 驱动器中。但是 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');
听起来 CME 可能阻止了 Apps 脚本。
今天看到几个这样的问题
对于 CME 阻塞(如果是这种情况),您无能为力,但有一种方法可以解决此问题,即使它需要访问浏览器。我注意到如果我使用 JavaScript fetch
API,它会 return XLS blob 正确,所以这里是使用 Apps Script Web App 的解决方法。
Index.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>
Code.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 应用程序才能执行它。
参考
我希望将一些文件保存到我的 Google 驱动器中。但是 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');
听起来 CME 可能阻止了 Apps 脚本。
今天看到几个这样的问题
对于 CME 阻塞(如果是这种情况),您无能为力,但有一种方法可以解决此问题,即使它需要访问浏览器。我注意到如果我使用 JavaScript fetch
API,它会 return XLS blob 正确,所以这里是使用 Apps Script Web App 的解决方法。
Index.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>
Code.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 应用程序才能执行它。