学校思政实践要收集1500份问卷,待在家里无聊就简单写了个用selenium模块实现的自动填写问卷xing问卷的小程序。

  基本思路很简单
  1.先打开问卷的网址,按F12进开发者模式分析页面HTML,找到题目的选项按钮对应的HTML代码(例如:Q1的四个选项按钮都在a标签内,且rel属性值分别为q1_1,q1_2,q1_3,q1_4);
  2.在py中用slenium的find_element_by_xpath+click()方法实现模拟点击按钮,例如:

q1 = random()
if 0 <= q1 <= 0.5:
    # 通过属性定位元素
    # q1_1是Q1的第1个按钮
    driver.find_element_by_xpath("//a[@rel='q1_1']").click()
else:
    driver.find_element_by_xpath("//a[@rel='q1_2']").click()

  3.若想模拟人的选择偏好,就用随机数区间+if语句控制,无非就是多写几条语句;
  4.最后填写完问卷提交也是一样的,find_element找到提交按钮的html对应代码再click()。此时要注意——在py中用selenium模拟填写的问卷最后点击提交必定触发智能验证框:
在这里插入图片描述
  这时你无论用人手点击或者是再模拟点击都是没法验证成功的
在这里插入图片描述

  这是因为问卷xing网页有反爬机制会检查你是不是通过selenium访问网页的。大多数情况下,检测基本原理是检测当前浏览器窗口下的window.navigator对象是否包含webdriver这个属性。因为在正常使用浏览器的情况下,这个属性是undefined,然而一旦我们使用了selenium,selenium会给window.navigator设置webdriver属性。很多网站就通过JS判断如果webdrive 属性存在,那就直接屏蔽。

  网上搜了一下,基本看着都是用pyppeteer解决反爬的方法,安装python第三方库asyncio、pyppeteer和pyppeteer_stealth然后一顿操作猛如虎似乎可以绕过智能验证?这个方法我没试,大家可以试试看,附上相关博文:使用Python自动填写问卷星(pyppeteer反爬虫版)
  我参考了某位知乎答主的方法——
  通过 CDP 实现在每个页面刚加载的时候执行JS代码,执行的CDP方法叫作Page.addScriptToEvaluateOnNewDocument。传入一段JS代码:

url = "http://www.baidu.com" #实例url
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
browser.get(url)

这样就可以在每次页面加载之前将webdriver属性置空从而躲过智能检测。

部分代码如下:

from selenium import webdriver
import time
from random import *

print("正在执行操作......")
# 给出所需的url和option参数
url_survey = ("https://www.wjx.cn/xx/xxxxxxx.aspx") # 根据需要填写url
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=option)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
driver.get(url_survey)
time.sleep(2)

# 处理Q1
# 生成随机数,决定点哪个按钮
q1 = random()
if 0 <= q1 <= 0.5:
    # 通过属性定位元素
    # q1_1是Q1的第1个按钮
    driver.find_element_by_xpath("//a[@rel='q1_1']").click()
else:
    driver.find_element_by_xpath("//a[@rel='q1_2']").click()

# 处理Q2
# 生成随机数,决定点哪个按钮
q2 = random()
if 0 <= q2 <= 0.25:
    driver.find_element_by_xpath("//a[@rel='q2_1']").click()
elif 0.25 < q2 <= 0.50:
    driver.find_element_by_xpath("//a[@rel='q2_2']").click()
elif 0.50 < q2 <= 0.75:
    driver.find_element_by_xpath("//a[@rel='q2_3']").click()
else:
    driver.find_element_by_xpath("//a[@rel='q2_4']").click()

# 处理Q3
# 生成随机数,决定点哪个按钮
q3 = random()
if 0 <= q3 <= 0.25:
    driver.find_element_by_xpath("//a[@rel='q3_1']").click()
elif 0.25 < q3 <= 0.50:
    driver.find_element_by_xpath("//a[@rel='q3_2']").click()
elif 0.50 < q3 <= 0.75:
    driver.find_element_by_xpath("//a[@rel='q3_3']").click()
else:
    driver.find_element_by_xpath("//a[@rel='q3_4']").click()
    

完整代码如下,欢迎小伙伴们fork or star:
Python+Selenium实现自动化刷问卷+绕过智能验证

上述代码亲测可用。

注意:当短时间内刷的问卷数过多时,可能会出现第二重智能验证,要拖动滑块进行验证,这个我暂时没有进行实验。

代码验证视频:
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐