我想我可能会迟到但仍然给你一个解决方案。我制作了类似的脚本来发送我的学校出勤率。
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))
希望对您有所帮助。对不起我的英语不好。