问卷星--问卷调查的正确填写方式

问卷星--问卷调查的正确填写方式

写这篇文章纯属一时兴起,是因为昨天协会群里有人发了问卷调查的链接,虽然这也很常见,之前空间也经常有人发问卷调查,但有的内容很长,问题又多,实在是麻烦得很。但是呢,作为一个程序猿,我觉得应该用我们方式去填问卷,其实只是我想皮一下。所以昨晚就写了个脚本,发现还真的挺好使的。

当时是在协会群里,原谅我不知道怎么地群里就开始开车了。好像大家对女装都挺感兴趣的,哈哈。而且群友的这句女装只有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://zgao.top',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()

最后效果还是非常好的,因为这是一个通用的脚本,对于问卷星的大部分问卷调查都能用。手动滑稽。

最后因为截图没有什么效果,所以我把这个脚本运行的过程录制成了一个视频在我空间里面。

zgao

如果有什么技术上的问题,可以加我的qq 1761321396 一起交流。