乐趣区

关于python:出于学习目的我多填了几个问卷

为了填写 WJ 星,我又拿起了 Python。

讲真,Python 可做的 Java 也能够,不过次要在于 Java 的依赖生态不迭 Python 欠缺,所以可能会更耗时一些,然而不代表 Java 比 Python 弱噢

背景

学校发了个表单,让填写一下

剖析历程

出于 好奇和学习 的心态,我想试下能不能主动填写表单;首先我想的是 JavaScript,因为毕竟是网页,所以首选的还是 JS,之后我创立了个 TEST 的表单进行测试,比拟每次申请的门路与参数。

首先 WJ 星 的页面里关上控制台后会进入 debug 模式,咱们须要 deactivate 掉断点才能够持续操作。Firefox 操作后会造成页面卡死,伤心,我这么爱它它却让我去找 Chrome…

错途

起初因为手速比较慢,只能拿到投票完之后的 url:https://www.wjx.cn/wjx/join/complete.aspx?activityid=109478233&joinid=108761857258&sojumpindex=1&comsign=135A7EC8CFEF9AFBE716B45BC4422FF56E5CB4F0&s=&njqj=1;通过屡次比对,发现其中的 joinid comsign 两个字段会发生变化,我认为这个对上后会发现生成所依赖的接口或者文件,这样之后通过生成这两个字段,循环就能重复刷票了。

起初发现自己 too simple 了,这条接口基本改不了投票的后果,也就是不作数!

之后进步手速,拿到了发送申请的接口地址:https://www.wjx.cn/joinnew/processjq.ashx? 一堆参数,如下所示

其中的外围参数是 jqparam 以及 jqsign。具体怎么生成的呢?参考一篇 52 上的剖析,走了一遍。

参考文章:对问卷星参数 jqparam 的剖析和摸索 https://www.52pojie.cn/forum…. 我这里就不再赘述了。

简言之就是应用插件重定向了 WJ 星 近程拜访的接口,而后本地去生成 jqparam,我试了试成果不大行。

那就手动主动吧

折腾完前边的之后发现走不过去,那就模仿点击吧~

于是我想到了 Selenium,大家当初也都在上人工智能的课,不论听没听,至多电脑上都该有个 Python 的环境吧~

pip install selenium  # 下载 selenium 到本地

之后咱们就有了根本,然而想要实现模仿点击,咱们还须要下载浏览器驱动,Firefox 摈弃了我,所以只好下载 Chrome 了。

驱动下载地址附上:http://chromedriver.storage.g…,抉择和本人浏览器大版本匹配的下载就可,下载解压后会失去一个 chromedriver.exe 复制到本人的 Python 装置目录下,这样默认就能够找到,不必再传参数了。

上边就绪后,咱们就来对页面进行剖析,有点相似于 Beautiful Soup

而后剖析页面,咱们发现,问卷主体内容都在 id="ctl00_ContentPlaceHolder1_JQ1_question" 的 div 盒子下,于是咱们确定了根节点。之后咱们再看第一个问题的地位

是在根目录下的 第二个 div 下的 第一个 fieldset 下的 第一个div;而后咱们定位一个问题的选项,是在再往下一级的 ulli 中。于是,咱们有了定位的门路。

 selection1 = '//*[@id="ctl00_ContentPlaceHolder1_JQ1_question"]/div[2]/fieldset[1]/div[1]/div[2]/ul/li'

之后咱们通过 webdriver.Chrome 来定位到 li,咱们发现实际上返回的是个列表

[<selenium.webdriver.remote.webelement.WebElement (session="93b4af8577a5b18396ea581abaa417ca", element="3ddfb20d-a1ef-4811-b49d-d50f70ab992f")>, <selenium.webdriver.remote.webelement.WebElement (session="93b4af8577a5b18396ea581abaa417ca", element="7db65e3e-2779-4180-be83-669ac2db1192")>]

咱们取出最初一个,而后执行 click() 操作,即可选中。

    answer_1 = driver.find_elements_by_xpath(selection1)[-1]
    answer_1.click()

其余选项同理,复选框也如此。最初咱们抉择提交即可。

认为到这里就完结了?我过后也这么感觉,然而咱们在提交后会呈现进行人机核验的弹窗,须要咱们额定解决下,同时还须要解决下拖动滑块验证。

在实际测验真谛的时候,发现了问题所在 在进行智能验证时,WJ 星会辨认 Selenium!,看来人家早就料到了啊。

至于说怎么辨认的呢?应用 selenium 的话,浏览器控制台会多出一个属性 window.navigator.webdriver 会变为 true,而当咱们失常拜访时它是 undefined 的。于是咱们须要暗藏掉这个属性,新版本的 Chrome (79 当前的) 须要通过 js 来进行暗藏,具体代码放在下方

driver = Chrome('./chromedriver')
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
  "source": """Object.defineProperty(navigator,'webdriver', {get: () => undefined
    })
  """
})

通过之后,这个表单终于能够提交了,先设置个次数?

for index in range(1, 200):

残缺代码如下:

import time
import random
from selenium import webdriver
from selenium.webdriver import ChromeOptions
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])

def autoFinishForm():
    # 将问卷星网站放在上面
    driver.get(' 群里的投票地址)

    # 单选题 1
    selection1 = '//*[@id="ctl00_ContentPlaceHolder1_JQ1_question"]/div[2]/fieldset[1]/div[1]/div[2]/ul/li'
    # print("log driver.find_elements_by_xpath(selection1):", driver.find_elements_by_xpath(selection1));
    answer_1 = driver.find_elements_by_xpath(selection1)[-1]
    answer_1.click()

    # 单选题 2
    selection2 = '//*[@id="ctl00_ContentPlaceHolder1_JQ1_question"]/div[2]/fieldset[1]/div[2]/div[2]/ul/li'
    answer_2 = driver.find_elements_by_xpath(selection2)[-1]
    answer_2.click()

    # 单选题 3
    selection3 = '//*[@id="ctl00_ContentPlaceHolder1_JQ1_question"]/div[2]/fieldset[1]/div[3]/div[2]/ul/li'
    answer_3 = driver.find_elements_by_xpath(selection3)[-1]
    answer_3.click()


    # 提交按钮
    submit = driver.find_elements_by_id('submit_button')[0]
    submit.click()

    # 提交后的验证弹窗
    alterPath = '//*[@id="alert_box"]/div[2]/div[2]/div[2]/button'
    checkButton = driver.find_elements_by_xpath(alterPath)[0]
    checkButton.click()

    # 智能验证按钮
    captchaout = '//*[@id="captchaout"]/div[1]'
    captchaoutBtn = driver.find_elements_by_xpath(captchaout)[0]
    captchaoutBtn.click()

    time.sleep(3)

    # 拖动滑块的反向操作:关掉再点 SM_POP_CLOSE_1
    # closeslipper = '//*[@id="submit_div"]/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]/div[1]/span'
    # closeslipperBtn = driver.find_elements_by_xpath(closeslipper)[0]
    closeslipperBtn = driver.find_elements_by_xpath("//div[@id='SM_POP_CLOSE_1'and @class='sm-pop-close']")[0]
    closeslipperBtn.click()
    captchaoutBtn.click()

    time.sleep(3)
    driver.quit()

if __name__ == '__main__':  
    # 循环 200 次
    for index in range(1, 200):
        driver = webdriver.Chrome(options=option)
        driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
            "source": """Object.defineProperty(navigator,'webdriver', {get: () => undefined
                })
            """
        })
        autoFinishForm()

关注 做棵大树,查看更多好玩的事儿

退出移动版