首页 > 解决方案 > 如何在电子表格列的单元格中迭代指向谷歌表单的链接以获取他们的问题?

问题描述

我有一个带有问卷链接的 Google 电子表格。我想知道如何从每份问卷中得到问题。

水图像介绍

我想我必须这样做:最好的情况是使用脚本编辑器并在行上进行迭代,最坏的情况是进行网络抓取。

const puppeteer = require('puppeteer');

function appendString() {
  var range = SpreadsheetApp.getActiveSheet().getActiveRange();
  var numRows = range.getNumRows();
  var numCols = 0;
  for (var i = 1; i <= numRows; i++) {
    for (var j = 1; j <= numCols; j++) {
      var currentValue = range.getCell(i,j).getValue();
      await page.goto(currentValue);

      const pollFrame = page.frames().find() # From there I have some difficulties
      
    }
  }
}

但我收到以下错误:

SyntaxError: await is only valid in async function (ligne 10, fichier "Code.gs")

更不用说异步问题或我仍然必须单击的按钮,选择如下所示:

<div class="freebirdFormviewerViewItemsItemItemTitle exportItemTitle freebirdCustomFont" id="i1" role="heading" aria-level="3" aria-describedby="i.desc.310938276">How often did you fly before the Covid-19 epidemic? </div>

但是ID不遵循逻辑数字顺序,所以我不知道如何自动提取它们。

然后我不知道该怎么做。我想知道它是否更简单,因为它们是来自同一供应商的产品。

这是 csv 格式的等价物:

https://docs.google.com/forms/d/e/1FAIpQLSfzocEm6IEDKVzVGOlg8ijysWZyAvQur0NheJb_I_xozgKusA/viewform?usp=sf_link
https://docs.google.com/forms/d/e/1FAIpQLScrm0ZTrvlONf5MX37N93H_FajNzfbNy9ZtitX-Vq9PPuLPHA/viewform?usp=sf_link

https://docs.google.com/forms/d/e/1FAIpQLSeolFSh3OyS_XpX1lRIJP-8CH8WG0X0hL98SM9d85LqC22Bow/viewform?usp=sf_link

更新

所以我尝试了 Neven Subotic 的友好发布的答案:

// this array will store forms and their questions
let formAndQuestions = [];

let formIds = ["https://docs.google.com/forms/d/e/1FAIpQLSfzocEm6IEDKVzVGOlg8ijysWZyAvQur0NheJb_I_xozgKusA/viewform?usp=sf_link",
        "https://docs.google.com/forms/d/e/1FAIpQLScrm0ZTrvlONf5MX37N93H_FajNzfbNy9ZtitX-Vq9PPuLPHA/viewform?usp=sf_link",
        "https://docs.google.com/forms/d/e/1FAIpQLSeolFSh3OyS_XpX1lRIJP-8CH8WG0X0hL98SM9d85LqC22Bow/viewform?usp=sf_link"]

formIds.forEach( formId => {
  const form = FormApp.openById( formId );
  // lets get the name
  const formName = form.getTitle();
  // first we get all items
  const allItemsInThisForm = form.getItems();

  // then we get filter out anything that is not a questions
  const allQuestionsInThisForm = allItemsInThisForm.filter( item => {
      return isThisItemAQuestion( item )
  });

  // now we store them in our object
  formAndQuestions.push( {
    formId: formId,
    formName: formName,
    questions: allQuestionsInThisForm
  })
});

// this function is used to only get the itemTypes you want
// see reference for more information
function isThisItemAQuestion( item ){
  const itemType = item.getType();
  const validQuestionItemTypes = [ FormApp.ItemType.TEXT, "add others here" ]
  let isValid = false;

  validQuestionItemsTypes.forEach( validItemType => {
    if( itemType == validItemType ) {
      isValid = true;         
    }
  });
  return isValid
}

不幸的是,我收到了带有以下详细信息的以下错误消息Exception: No item with the given ID could be found, or you do not have permission to access it. (line 9, "const form = FormApp.openById( formId );")。我不明白。正如你在 gif 中看到的,我可以打开这些链接,所以我应该有权访问它们,不是吗?

我还尝试了鲁本的想法:

// this array will store forms and their questions
let formAndQuestions = [];

let formIds = ["https://docs.google.com/forms/d/e/1FAIpQLSfzocEm6IEDKVzVGOlg8ijysWZyAvQur0NheJb_I_xozgKusA/viewform?usp=sf_link"]//,
        //"https://docs.google.com/forms/d/e/1FAIpQLScrm0ZTrvlONf5MX37N93H_FajNzfbNy9ZtitX-Vq9PPuLPHA/viewform?usp=sf_link",
        //"https://docs.google.com/forms/d/e/1FAIpQLSeolFSh3OyS_XpX1lRIJP-8CH8WG0X0hL98SM9d85LqC22Bow/viewform?usp=sf_link"]


function scrapeForms(){
  formIds.forEach( formId => {
                  // The code below logs the HTML code of the Google home page.
                  var response = UrlFetchApp.fetch(formId);
                  results = response.getElementsByClassName("freebirdFormviewerViewItemsItemItemTitleContainer");
                  Logger.log(results.getContentText())
  });
}

但是回来了:

TypeError: response.getElementsByClassName is not a function (ligne 13, fichier "Code")

标签: javascriptgoogle-apps-scriptgoogle-sheetspuppeteergoogle-forms

解决方案


根据这个Javascript“要求”是什么? require不是标准 JavaScript 的一部分,它不受 Google Apps 脚本支持。

另一方面,由于 Google Apps Script Chrome V8 引擎不支持异步功能,因此无法轻松解决错误消息。相关谷歌应用程序脚本是否同步?


如果您将使用 Google Apps 脚本,并且您是表单所有者或表单编辑者,则不要尝试从网络抓取 Google 表单,而是使用 Google Apps 脚本的表单服务。为此,您将需要表单../editURL 而不是../viewform URL。在官方文档中,有一个快速入门可能会对您有所帮助https://developers.google.com/apps-script/quickstart/forms

您可以使用openByUrl来“打开”一个表单。它实际上不会在您的网络浏览器中打开,它将在服务器端打开。然后你可以使用getItems来获取所有的问题、部分、图像、视频等。

如果您不是表单所有者或表单编辑器,那么您应该使用UrlFetchApp服务并根据问题的位置以某种方式解析每个表单的网页源代码。相关问题:谷歌表格:如何导入以下数据?

此外,如果表单有多个部分,您应该发出一个发布请求来模拟单击下一步按钮以获得第二个和后续部分。还有更多“如果表格有......”但我会在这里停下来,因为问题的主要部分已经回答了,我想。


推荐阅读