【问题标题】:Auto-Fill or automate a Google Form自动填写或自动化 Google 表单
【发布时间】:2020-05-17 09:36:38
【问题描述】:

随着预算学校最近匆忙实施的在家学习动态,我现在面临着一项类似机器人的无意识任务,即每个孩子每天多次为我的孩子填写出勤记录。学校分享了这个表格:

作为一名开发人员,我想要创建一个 UI,并让我的孩子们在老师要求 Zoom 时自行提交他们的出勤率。有可能吗?我是一名 .Net 开发人员,还没有为 Office 365 Online 开发过任何东西,也不知道从哪里开始寻找 Google。

【问题讨论】:

    标签: google-forms


    【解决方案1】:

    可以通过使用预填充值重构表单 URL。 在 Google 表单中,每个问题在内部都以“entry.”命名。对于每个问题,您需要找到条目编号并为其分配正确的值并将其添加到 URL 参数中,如下图所示: (2021 年 10 月编辑:如图所示,不再在 HTML 中每个输入字段的名称属性中找到 ID。它们现在位于 form 元素内的 div 中。@hdrz 的答案如下所示在 Javascript 中出现在 body 标记末尾的现在也已失效。)

    我在这里重新创建了您的表单https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform

    这是带有预填充值的重构 URL https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/viewform?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E

    希望对你有帮助

    【讨论】:

    • 嗯嗯嗯嗯嗯嗯。我想我仍然需要抓取页面来填写名称,但这很有趣。 :)
    • 好的,我试过了,但是当我抓取我的表单时,这些值不在 HTML 中。所有表单元素都缺少 name 和 id 属性。此外,当我查看 your 表单时,我也看不到表单上的值。但是,您的预填充 URL 确实有效。因此,目前缺少的只是如何首先获取值。
    • 关于这个解决方案,有人如何格式化查询字符串以自动填充表单 DD/MM 的日期输入字段?在我看来,它需要两个参数。
    【解决方案2】:

    正如@AHunt 所写,条目号曾经位于表单字段的name 属性中。截至本回答时间,我无法再在任何表单字段上找到 name 属性。但是,现在body 标记末尾有一个script 标记,带有一个简短的 javascript 代码,您可以在其中找到条目编号,请参见此处:

    此外,还可以使用预先填写的值直接提交表单。只需将 URL 中的 viewform 替换为 formResponse

    与已接受答案中的类似 URL,但现在将立即提交。请注意,所有必填字段都必须填写!

    https://docs.google.com/forms/d/e/1FAIpQLSfrGn49hcbeioNNa25Osp4fwTG2xV3BmmN9-cMWWC2-xvcQyg/formResponse?entry.1475351979=Julia&entry.280503419=Andrews&entry.519373518=4&entry.301819105=E&entry.1124370742=Art

    【讨论】:

      【解决方案3】:

      我想我可能会迟到但仍然给你一个解决方案。我制作了类似的脚本来发送我的学校出勤率。 Google 表单中的每个字段都与 entry.<id> 相关联。您有两种方法可以自动生成表单。

      一种方法是提取这些 ID 并制作一个字典,其中 entry.<id> 是键,您的答案是值。然后您必须向表单 URL 发送 POST 请求,并将字典作为数据。您已自动生成表单。

      要提取 ID,请检查 html 代码并查看页面(非常)末尾的 <script>。它看起来像这样:

      var FB_PUBLIC_LOAD_DATA_ = [null,[null,[[2030831236,"First Name (in English)",null,0,[[1475351979,null,1]
      ]
      ]
      ,[86681139,"Last Name (in English)",null,0,[[280503419,null,1]
      ]
      ]
      ,[836880978,"Grade",null,2,[[519373518,[["KG 1",null,null,null,0]
      ,["KG 2",null,null,null,0]
      ,["1",null,null,null,0]
      ,["2",null,null,null,0]
      ,["3",null,null,null,0]
      ,["4",null,null,null,0]
      ,["5",null,null,null,0]
      ,["6",null,null,null,0]
      ,["7",null,null,null,0]
      ,["8",null,null,null,0]
      ,["9",null,null,null,0]
      ,["10",null,null,null,0]
      ,["11",null,null,null,0]
      ,["12",null,null,null,0]
      ]
      ,1,null,null,null,null,null,0]
      ]
      ]
      ,[221348070,"Section",null,2,[[301819105,[["A",null,null,null,0]
      ,["B",null,null,null,0]
      ,["C",null,null,null,0]
      ,["D",null,null,null,0]
      ,["E",null,null,null,0]
      ,["G",null,null,null,0]
      ]
      ,1,null,null,null,null,null,0]
      ]
      ]
      ,[366027193,"Subject",null,2,[[1124370742,[["Math",null,null,null,0]
      ,["Science",null,null,null,0]
      ,["English",null,null,null,0]
      ,["Arabic",null,null,null,0]
      ,["Islamic",null,null,null,0]
      ,["Social",null,null,null,0]
      ,["Moral",null,null,null,0]
      ,["Art",null,null,null,0]
      ,["Computer",null,null,null,0]
      ,["French",null,null,null,0]
      ,["Physics",null,null,null,0]
      ,["Chemistry",null,null,null,0]
      ,["Biology",null,null,null,0]
      ,["Business",null,null,null,0]
      ]
      ,1,null,null,null,null,null,0]
      ]
      ]
      ]
      ,null,null,[null,null,null,null,null,[null,null,null,[3,169,244,null,1]
      ,[217,242,253,null,1]
      ]
      ]
      ,null,null,null,"Attendance Form",48,null,null,null,null,null,[2]
      ]
      

      如您所见,每个字段都有两个数字。其中一个是ID,另一个是我不知道的。第二个数字是我们需要的 ID。使用 RegEx,我们可以提取所有数字并收集列表中的每个第二个数字。此列表将包含所有 ID。

      正如其他人所说,另一种方法是使用预填充值重建 URL。但是在这个过程中,您也必须提取 ID。

      我已将它们合二为一并制作了这个脚本:

      import requests
      from bs4 import BeautifulSoup
      import re
      
      def get_questions(url):
          
          page = requests.get(url)
          soup = BeautifulSoup(page.content, 'html.parser')
          
          content = soup.body.find_all(text = re.compile('var FB'))
          
          match = re.findall('[,]["][\w\s]+["][,]', str(content))
          #It will match all the questions in the form
          question_strings = [x.strip('"') for x in match]
          
          match_ids = re.findall('(?<=\[\[)(\d+)', str(content))
          #It will find all the numbers in the content
          question_ids = ['entry.' + x for x in match_ids[1:]]
          #It will leave the first numbers (they are not the ids)
          return question_ids
          
      # Below are only for when you want to know the form fills with their corresponding entry ids
      #    questions = dict(zip(question_strings, question_ids))    
      #    return questions
      
      
      def send_answers(url, fname, lname, grade, section, subject): #arrange this as per your form requirements
          
          ids = get_questions(url)
          
          answers = [fname, lname, grade, section, subject]
          response = dict(zip(ids, answers))
          
          if 'viewform' in url:
              s = url.index('viewform') 
              response_url = url.replace(url[s::], 'formResponse?')
              
          try:
              r = requests.post(response_url, response)
              if r.status_code == 200:
                  return '[!] Attendence posted !'
              #In case an error happens, it will raise an exception
              else:
                  raise Exception
      
          #After raising the exception it will retry to submit using url reconstruction with prefilled values
          except:
              try:
                  ans_list = [x + '=' + y for x, y in zip(ids, answers)]
                  
                  for i in range(0, len(ans_list)):
                      response_url += ans_list[i]
                      response_url += '&'
                      
                  response_url.strip("&")    
                  r = requests.get(response_url)
                  status = r.status_code
                  
                  if status == 200:
                      return '[!] Attendance sent !'
                  else:
                      raise Exception
              #If still an error happens, it will print out a message.
              except:
                  return '[!] Attendance not sent !'
                      
      
      url = 'Form URL here'
      
      fname = 'Your first name here'
      lname = 'Your last name here'
      grade = 'Your grade here'
      section = 'Section here'
      subject = 'Enter subject'
      
      print(send_answers(url, fname, lname, grade, section, subject))
      

      希望对您有所帮助。对不起我的英语不好。

      【讨论】:

      • 获得 401 响应状态
      【解决方案4】:

      作为 Google 表单编辑器,您可以通过选择“点击三个点后,页面右上角的获取预填充链接'选项。

      这将在新选项卡中打开表单。 提交 (或下一步按钮将替换为“获取链接”按钮。

      填写所需的表单回复后,点击“获取链接”将打开用户将看到的预览。如果一切正确,点击“复制链接”按钮(位于页面左下方)将提供 URL。

      网址将如下所示:

      https://docs.google.com/forms/d/e/yourFormidhere/viewform?usp=pp_url&entry.1890935147=exampleprefilledvalue1&entry.1928475566=exampleprefilledvalue2&entry.2145528193=exampleprefilledvalue3

      【讨论】:

      • 感谢您提供此信息。在这种情况下,我不是编辑,但我可以创建一个示例来了解 URL 中生成的不同返回
      【解决方案5】:

      您可以在 Chrome 的控制台开发部分找到这些 ID。
      填写表格打开网络标签。
      您可以在表单中找到每个查询的 ID。

      【讨论】:

        猜你喜欢
        • 2011-07-10
        • 1970-01-01
        • 2013-07-30
        • 1970-01-01
        • 1970-01-01
        • 2014-12-17
        • 2021-11-12
        • 1970-01-01
        相关资源
        最近更新 更多