У меня уже некоторое время (год) работает скрипт Google Sheets, которому нужно прочитать файл HTML из каталога Google Диска. Код для открытия файла выглядит так:

var myHtmlFile = UrlFetchApp.fetch("https://googledrive.com/host/0B1m........JtZzQ/myfile.htm");

... и я мог бы использовать файл HTM для дальнейшего анализа.

Внезапно приведенный выше код выдает ошибку 404.

Изменилось ли что-нибудь в последнее время, что мешает мне открыть файл?

0
seanpj 11 Ноя 2014 в 02:14

2 ответа

Я нахожу странным, что это когда-либо работало раньше! Если это так, то, вероятно, это была ошибка - почти уверен, что она никогда не предназначалась для такой работы с "локальными" файлами... Я никогда не видел, чтобы где-либо упоминалось, что UrlFetchApp.fetch() может извлекать "локальные" файлы таким образом.

Простым решением было бы просто использовать правильный полный URL-адрес файла:

var myHtmlFile = UrlFetchApp.fetch("https://googledrive.com/host/{public_folder_id}/myfile.htm");

Это гарантирует, что ваш код соответствует API и не сломается, когда Google что-то изменит в следующий раз.

0
azawaza 11 Ноя 2014 в 04:10
Интересно, ваш скрипт перестает работать из-за принудительного переноса старого листа (созданного до декабря 2013 года) на новые листы, который начался сегодня…
 – 
azawaza
11 Ноя 2014 в 06:06
На самом деле, я облажался, когда писал вопрос, параметр URL-адреса в fetch был правильным URL-адресом, то есть: «googledrive.com/host/0B1m........dQ3U4eDFXNjJtZzQ/myfile.htm", где "0B1m........dQ3U4eDFXNjJtZzQ" {public_folder_id} в вашем ответе, поэтому звонок прошел нормально. Он просто перестал работать сегодня, но может быть с перебоями (как и многие другие вещи с Диском). Я перезапущу его позже и посмотрю.
 – 
seanpj
11 Ноя 2014 в 06:13
Определенно это может быть просто временная проблема с Диском. Однако, если проблема не устранена в течение нескольких часов, это может быть что-то еще — попробуйте сохранить новую версию вашего скрипта и повторно развернуть ее как наше приложение (если это веб-приложение). Если это сценарий, связанный с листом, попробуйте создать новую электронную таблицу и скопировать в нее свой сценарий, чтобы проверить, будет ли он работать.
 – 
azawaza
11 Ноя 2014 в 06:21
Тайна раскрыта. Я получал {PublicFolderId} из конструкции, которая включала что-то вроде "var thisFile = DocsList.getFileById(SpreadsheetApp.getActive().getId())"... и... "thisFile.getParents()[0]. получить идентификатор()'. Мне кажется, что «DocsList» создает идентификаторы, но, вероятно, уже недействительные. Я помню, что где-то видел, что это устарело?
 – 
seanpj
11 Ноя 2014 в 07:13
1
DocsList не устарел — по крайней мере, пока — но это «экспериментальная» служба, что означает, что она может быть прекращена в любое время (например, Google прекратил службу ScriptDb). По всей вероятности, в конечном итоге его заменит Drive Service. Однако вернемся к вашей проблеме: может быть, у вашего файла теперь несколько родителей (по какой-то причине) и thisFile.getParents[0] больше не указывает на общую папку, а на какую-то другую папку?
 – 
azawaza
11 Ноя 2014 в 07:29

После обсуждения с «азаваза» (спасибо за все советы) я, наконец, решил эту проблему, поэтому я публикую решение на случай, если другие попадут в это.

Похоже на конструкцию

https://googledrive.com/host/{public_folder_id}/myfile.htm

В UrlFetchApp.fetch(url, true) больше нельзя использовать. Выдает ошибку 404.

Я получил его из следующей конструкции (для простоты, предполагая, что у моей электронной таблицы есть только одна родительская папка):

  ...
  var myId = DocsList.getFileById(SpreadsheetApp.getActive().getId());
  var folderId = myId.getParents()[0].getId();
  var url = "https://googledrive.com/host/" + folderId + "/myfile.htm";

  // url looks like: https://googledrive.com/host/0B1m....JtZzQ/myfile.htm"
  var httpResp = UrlFetchApp.fetch(url,true);   //throws 404 !!!
  // now, parse 'httpResp'

Решение, которое сработало для меня, состоит в том, чтобы найти файл напрямую, используя эту конструкцию (опять же, при условии, что существует только один файл с заданным именем):

   var htmlCont = DocsList.find("myfile.htm")[0].getContentAsString(); 
   // now, parse htmlCont

Я не знаю, почему «старое» решение больше не работает. Как я уже сказал, он работал в течение года.

ОБНОВЛЕНИЕ (май 2015 г.)
«Список документов» устарел, новая конструкция:

  var files = DriveApp.getFilesByName(myURL);
  if (files.hasNext()) {
    var htmlCont = files.next().getBlob().getDataAsString()
  }

Вместо этого следует использовать

0
seanpj 3 Май 2015 в 00:55