Based on the answer from @pigletfly I wrote a little script for harvesting the field names (for a text-field only form)
import urllib.request
from bs4 import BeautifulSoup
import requests, warnings
def get_questions(in_url):
res = urllib.request.urlopen(in_url)
soup = BeautifulSoup(res.read(), 'html.parser')
get_names = lambda f: [v for k,v in f.attrs.items() if 'label' in k]
get_name = lambda f: get_names(f)[0] if len(get_names(f))>0 else 'unknown'
all_questions = soup.form.findChildren(attrs={'name': lambda x: x and x.startswith('entry.')})
return {get_name(q): q['name'] for q in all_questions}
def submit_response(form_url, cur_questions, verbose=False, **answers):
submit_url = form_url.replace('/viewform', '/formResponse')
form_data = {'draftResponse':[],
'pageHistory':0}
for v in cur_questions.values():
form_data[v] = ''
for k, v in answers.items():
if k in cur_questions:
form_data[cur_questions[k]] = v
else:
warnings.warn('Unknown Question: {}'.format(k), RuntimeWarning)
if verbose:
print(form_data)
user_agent = {'Referer':form_url,
'User-Agent': "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36"}
return requests.post(submit_url, data=form_data, headers=user_agent)
You can then use the get_questions function to get the fields which you can fill in
TEST_FORM_URL = "https://docs.google.com/forms/d/e/1FAIpQLSfBmvqCVeDA7IZP2_mw_HZ0OTgDk2a0JN4VlY5KScECWC-_yw/viewform"
anno_questions = get_questions(TEST_FORM_URL)
To get the questions (fields) as a dict
{'annotator': 'entry.756364489',
'task': 'entry.1368373366',
'item_id': 'entry.84713541',
'label': 'entry.2072511216',
'session': 'entry.2021127767',
'time': 'entry.1122475936'}
then use the submit_response with keyword arguments to submit
submit_response(TEST_FORM_URL, anno_questions, annotator="TestUser", item_id = 0)