def test_submit_not_loaded(self): form = Form() with pytest.raises(FormNotLoaded): form.submit()
def main(): ua = FakeUserAgent() # A session for form loading and submission sess = requests.session() sess.headers['User-Agent'] = ua.chrome # Mean time between submissions mean_dt = 60 parser = argparse.ArgumentParser() parser.add_argument( 'url', help='The form url (https://docs.google.com/forms/d/e/.../viewform)') args = parser.parse_args() form = Form() form.load(args.url, session=sess) filler = Filler() # Show the form print(form.to_str(2)) # Use filler to cache custom callback values, if needed (will be reused later) form.fill(filler.callback, fill_optional=True) # Show the form with answers print(form.to_str(2, include_answer=True)) print() for i in range(10): last = time_now() print(f'[{asctime()}] Submit {i+1}... ', end='') sep = '' filled = False for _ in range(10): # Retry if InfiniteLoop is raised try: form.fill(filler.callback, fill_optional=True) filled = True break except InfiniteLoop: sep = ' ' print('X', end='') sleep(0.1) except ValidationError as err: # Most probably the default callback failed on an element with a validator. print(f'{sep}Failed: {err}') sleep(1) break if not filled: continue try: form.submit(session=sess) # You may want to use history emulation: # submission is faster, but it is still experimental # form.submit(session=sess, emulate_history=True) print(sep + 'OK', end='') except ClosedForm: print(sep + 'Form is closed') break except RuntimeError: # Incorrect response code or page prediction failed print(sep + 'Failed', end='') # Poisson distribution for (submissions / timeframe) delta = random.expovariate(1 / mean_dt) print(f', sleeping for {round(delta)}s') sleep(max(0.0, last + delta - time_now()))