问卷星–问卷调查的正确填写方式
写这篇文章纯属一时兴起,是因为昨天协会群里有人发了问卷调查的链接,虽然这也很常见,之前空间也经常有人发问卷调查,但有的内容很长,问题又多,实在是麻烦得很。但是呢,作为一个程序猿,我觉得应该用我们方式去填问卷,其实只是我想皮一下。所以昨晚就写了个脚本,发现还真的挺好使的。
当时是在协会群里,原谅我不知道怎么地群里就开始开车了。好像大家对女装都挺感兴趣的,哈哈。而且群友的这句女装只有0次和无数次确实有点内涵,手动滑稽。
因为之前也经常有人发这种调查问卷,所以我一直都想自己写一个脚本写帮各位填一下,恰好昨天又刚好有空,打开了我的pycharm直接开干。因为之前我抓过问卷星表单提交的数据包,好像是被加过密的。所以肯定不能用发包的形式来做。所以我的思路就转向了selenium,直接操作浏览器模拟真实的鼠标点击来完成问卷的。
这里就以这份古装的问卷调查为例,我们先打开浏览器用开发者工具对页面的主体部分进行。
而所有的div标签又是放在了fieldset标签内的,所以我们的思路就是先通过元素定位,缩小范围再进行标签的遍历。
继续分析单个选项,就比如第一题是单选题,观察源码。
而且仔细观察后会发现其实每一题(单选和多选)的a标签的class的值其实都是一样的,那么直接写一个for循环即可,对所有的a标签遍历模拟点击。
同理,对于填空题这类的题型的分析方法也是一样的。
不断地试验之后,发现想法是可行的,但是一看就知道不是人为点击。
为什么呢? 单选题的选项是互斥的,多选则都行。因为遍历时顺序是依次的,所以单选题点击到最后一个时就会只选上最后一个选项了,多选题同理。
这肯定不是我们想要的结果,所以我们要加入一些随机的选择进去,即看起来更像是人为点击。这里我就直接上代码了,第一个版本的。
from selenium import webdriver from selenium.webdriver.common.keys import Keys import random import time def click(i,tag): tr = i.find_elements_by_tag_name(tag) for r in tr: a = r.find_elements_by_tag_name('a') randnum = random.randint(0, len(a)) for k, n in enumerate(a): try: n.click() if k == randnum: break except: pass def input_info(i,class_name,info): text = i.find_elements_by_class_name(class_name) for i in text: try: i.click() i.send_keys(info) except: pass def submit_content(i): randcontent = ['无可奉告','不清楚','不知道','还行','不错','ok','可以'] info = random.choice(randcontent) input_info(i,'inputtext',info) input_info(i,'underline',info) input_info(i,'lisort',info) def main(): div_question = chrome.find_elements_by_class_name('div_question') for i in div_question: click(i,'ul') click(i,'tr') submit_content(i) submit = chrome.find_element_by_id('submit_button').click() if __name__ == '__main__': url = input('请输入问卷星的问卷调查链接:') chrome = webdriver.Chrome() chrome.get(url) main() time.sleep(2) for i in range(1): chrome.get(url) main() chrome.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') print('问卷填写完成!') chrome.quit()
在我定义的click函数中,也就是
其中a是一个列表,取一个随机整数在0到a列表长度之间,k是n的索引值,一开始还是先点击,如果在索引值等于了这个随机数,就跳出循环,不再点击下面的选项了,这样看起来就很自然了。同样填空题思路也是一样的,只不过定义了一个列表来随机填入而已。最后模拟点击提交就ok了。
其实这样已经实现整个填写问卷的过程了。
但是,作为一只渗透狗,难道这样就结束了??
肯定不会,思维要横向拓展,更骚一点才行!如果我想给别人恶意刷大量问卷调查的垃圾数据该怎么做呢?
有些问卷他是限制了你的ip的,一个ip只允许填写一次,这样可就很为难了。等等,反过来想想,这不是类比反爬吗?我限制了你的ip,但是我可以用ip代理池来应对呀!想想我博客之前的一篇文章。
爬取西刺代理写入Redis数据库自建免费IP代理池
在这篇文章中,我通过爬取西刺代理的免费高匿ip写入redis供平时使用,那这里我也可以从redis中取出可用ip。完整代码如下
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.proxy import Proxy from selenium.webdriver.common.proxy import ProxyType import random import requests import redis import time redis_pool = redis.ConnectionPool(host='ip',password='密码',port=端口) redis_con = redis.Redis(connection_pool=redis_pool) def proxies_ip(ip): if 'https' not in ip:proxies={'http':ip} else:proxies={'https':ip} return proxies def get_proxies(): #这个while True 在这里针对我的redis写的。自己用时自行修改 while True: ip = redis_con.get(random.randint(0, 500)) if ip: ip = str(ip)[2:-1] try: r = requests.get('http://106.15.73.80',proxies=proxies_ip(ip), timeout=1, verify=False) #验证该代理是否可用 break except Exception as e: continue print('正在使用代理',ip) return ip def click(i,tag): tr = i.find_elements_by_tag_name(tag) for r in tr: a = r.find_elements_by_tag_name('a') randnum = random.randint(0, len(a)) for k, n in enumerate(a): try: n.click() if k == randnum: break except: pass def input_info(i,class_name,info): text = i.find_elements_by_class_name(class_name) for i in text: try: i.click() i.send_keys(info) except: pass def submit_content(i): randcontent = ['无可奉告','不清楚','不知道','还行','不错','ok','可以'] info = random.choice(randcontent) input_info(i,'inputtext',info) input_info(i,'underline',info) input_info(i,'lisort',info) def main(): div_question = chrome.find_elements_by_class_name('div_question') for i in div_question: click(i,'ul') click(i,'tr') submit_content(i) submit = chrome.find_element_by_id('submit_button').click() if __name__ == '__main__': url = input('请输入问卷星的问卷调查连接:') proxy = Proxy({'proxyType': ProxyType.MANUAL, 'httpProxy': 'ip:port'}) chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--proxy-server={}'.format(get_proxies())) chrome = webdriver.Chrome() #chrome.maximize_window() chrome.get(url) main() for i in range(1): time.sleep(2) chrome.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') chrome_options.add_argument('--proxy-server={}'.format(get_proxies())) chrome.get(url) main() chrome.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') print('问卷填写完成!') chrome.quit()
最后效果还是非常好的,因为这是一个通用的脚本,对于问卷星的大部分问卷调查都能用。手动滑稽。
最后因为截图没有什么效果,所以我把这个脚本运行的过程录制成了一个视频在我空间里面。
赞赏微信赞赏支付宝赞赏
目前为止有一条评论