利用Python實(shí)現(xiàn)問(wèn)卷星自動(dòng)填寫(xiě)的超詳細(xì)教程
前言
(Ps:廢話部分可跳過(guò) )相信大家一定都有被問(wèn)卷給折磨的時(shí)候,尤其去求別人填問(wèn)卷的時(shí)候,如果是內(nèi)向的小伙伴就一定很苦惱了,那么有沒(méi)有一種工具可以幫助我們?nèi)プ詣?dòng)填寫(xiě)問(wèn)卷以達(dá)到問(wèn)卷不求人的東西呢!答案是肯定的,我們都知道python是門很強(qiáng)大的語(yǔ)言,在自動(dòng)化、人工智能、數(shù)據(jù)分析等領(lǐng)域有著舉足輕重的作用,所以在這里我們選擇用python來(lái)實(shí)現(xiàn)。
一、配置環(huán)境
1.1安裝依賴
①這里我們需要用到python的庫(kù)函數(shù)——selenium庫(kù),這是幫助我們?nèi)ヅ廊【W(wǎng)頁(yè)信息和處理網(wǎng)頁(yè)的重要工具。也是我們本次實(shí)現(xiàn)程序所用到的庫(kù),直接在選擇好的環(huán)境下執(zhí)行
pip install selenium。
②我們還需要用到pyautogui庫(kù)函數(shù)去模擬人手點(diǎn)擊或拖拽來(lái)進(jìn)行智能驗(yàn)證,也是在對(duì)應(yīng)的環(huán)境執(zhí)行
pip install pyautogui。
pip install selenium pip install pyautogui
1.2安裝驅(qū)動(dòng)
執(zhí)行本次程序是在谷歌瀏覽器下完成的,所以在此之前請(qǐng)下載谷歌瀏覽器(谷歌瀏覽器下載地址)。
下好瀏覽器就可以去下載驅(qū)動(dòng)了,在這之前我們還需做一步,打開(kāi)已經(jīng)安裝好的谷歌瀏覽器,查看自己的瀏覽器版本。
到這里我們就可以下載谷歌驅(qū)動(dòng)了(Chrome驅(qū)動(dòng)鏈接),點(diǎn)擊進(jìn)去找到對(duì)應(yīng)的版本號(hào),如果沒(méi)有對(duì)應(yīng)的版本號(hào)下載接近的一個(gè)即可,如下版本里面沒(méi)有我的111.0.5563.65的版本,我們下載111.0.0.5563.64的即可(Ps:如果發(fā)現(xiàn)在后面打不開(kāi)驅(qū)動(dòng)出現(xiàn)錯(cuò)誤,換一個(gè)驅(qū)動(dòng)再試一下,因?yàn)檫@里有些人是要小一點(diǎn)的版本可以,有些人是大一點(diǎn)的版本可以)。
下載好是一個(gè)壓縮吧,解壓完成后是一個(gè).exe文件,可以放在任意的一個(gè)文件夾,只要能找到即可,我這里選擇的是放在安裝好的谷歌瀏覽器文件夾下。
二、實(shí)戰(zhàn)處理
2.1、引入庫(kù)函數(shù)
這里我們引入所要用到的庫(kù)函數(shù)及對(duì)應(yīng)的包
from selenium.webdriver.common.by import By # 沒(méi)有selenium庫(kù)的(請(qǐng)?jiān)谒玫沫h(huán)境下pip install selenium) from selenium import webdriver #selenium庫(kù) import random # 用于產(chǎn)生隨機(jī)數(shù) import time # 用于延時(shí) import pyautogui # 用于模擬人手
2.2、程序所需函數(shù)詳解
(1)自定義單選函數(shù)
當(dāng)問(wèn)卷中有單選就可以直接查詢到問(wèn)卷中的所有單選進(jìn)行自動(dòng)答題。
def danxuan(driver): # 找到所有標(biāo)簽(定位問(wèn)題)這里是單選 dan = driver.find_elements_by_css_selector('#div1 > div.ui-controlgroup.column1') for answer in dan: ans = answer.find_elements_by_css_selector('.ui-radio')#對(duì)應(yīng)的絕對(duì)子標(biāo)簽 random.choice(ans).click() # 找到標(biāo)簽并點(diǎn)擊 time.sleep(random.randint(0, 1))
(2)自定義多選函數(shù)
尋找問(wèn)卷中第幾題是多選,就可自動(dòng)去答多選中的題。
def duoxuan(driver): #這里是多選題,找到所有多選的標(biāo)簽 duo = driver.find_elements_by_css_selector('#div2 > div.ui-controlgroup.column1') for answer in duo: ans = answer.find_elements_by_css_selector('.ui-checkbox')#對(duì)應(yīng)的絕對(duì)子標(biāo)簽 #隨機(jī)填幾次 for i in range(1, 7):#這里的7可以改成5,10,12 random.choice(ans).click()#找到標(biāo)簽并點(diǎn)擊 time.sleep(random.randint(0, 1))
(3)自定義填空函數(shù)
需要自己去定義第幾題是填空并填上自己想要填寫(xiě)的內(nèi)容。
如果要修改可這樣改,例子:index里的數(shù)量一定要對(duì)應(yīng)answer里的數(shù)量,index的名字可以跟answer不一樣
index = [“1”, “2”, “B”, “D”]
answer = {“1”: “python真的好用!”, “2”: “這個(gè)測(cè)試很成功!”, “B”: “填空題隨機(jī)填寫(xiě)文本”,“D”: “隨便填寫(xiě)!”}
def tiankong(driver, num): #填空函數(shù) #這里是所需要問(wèn)題的標(biāo)簽匯總,例如有四個(gè)要答的問(wèn)題,下面的answer的ABC數(shù)量需要跟index里面的數(shù)量相等 index = ["A", "B", "C"] # 自定義要回答的答案 answer = {"A": "python真的好用!", "B": "這個(gè)測(cè)試很成功!", "C": "填空題隨機(jī)填寫(xiě)文本"} driver.find_element(by=By.CSS_SELECTOR, value=f'#q{num}')\ .send_keys(answer.get(index[random.randint(0, len(index)-1)]))
(4)自定義智能驗(yàn)證函數(shù)
當(dāng)出現(xiàn)智能驗(yàn)證的時(shí)候,用自定義的這個(gè)函數(shù)可以幫我們解決。
def renzheng(driver): # 智能驗(yàn)證,找到智能認(rèn)證的標(biāo)簽 bth = driver.find_element_by_css_selector( '#layui-layer1 > div.layui-layer-btn.layui-layer-btn- > a.layui-layer-btn0') bth.click()#點(diǎn)擊 time.sleep(1) rectBottom = driver.find_element_by_css_selector('#rectBottom') #提交按鈕 rectBottom.click() #點(diǎn)擊 time.sleep(5)
(5)自定義滑塊驗(yàn)證函數(shù)
當(dāng)填寫(xiě)問(wèn)卷次數(shù)過(guò)多,這時(shí)智能驗(yàn)證之后還會(huì)出現(xiàn)滑塊驗(yàn)證,這時(shí)候就需要滑塊驗(yàn)證函數(shù)幫我們解決。
def huakuai(): # 當(dāng)次數(shù)多了的時(shí)候就會(huì)出現(xiàn)滑塊,這里是模擬人手解決滑塊拖動(dòng) pyautogui.moveTo(random.randint(494, 496), 791, 0.2)#控制鼠標(biāo)移動(dòng)到x,y處,耗時(shí)0.2秒 time.sleep(1) pyautogui.dragTo(random.randint(888, 890), 791, 1)#讓鼠標(biāo)點(diǎn)擊并拖拽到x,y處,耗時(shí)1秒 time.sleep(1) pyautogui.click(random.randint(652, 667), random.randint(793, 795))#讓鼠標(biāo)點(diǎn)擊x,y處 time.sleep(1) pyautogui.moveTo(random.randint(494, 496), 791, 0.2)#控制鼠標(biāo)移動(dòng)到x,y處,耗時(shí)0.2秒 time.sleep(1) pyautogui.dragTo(random.randint(888, 890), 791, 1)#讓鼠標(biāo)點(diǎn)擊并拖拽到x,y處,耗時(shí)1秒
(6)自定義屏幕滾動(dòng)函數(shù)
當(dāng)問(wèn)卷中的題數(shù)量多的時(shí)候,由于答題過(guò)快,屏幕沒(méi)有滑動(dòng),這時(shí)會(huì)被檢測(cè)出是機(jī)器人,就會(huì)提交失敗,所以我們還需要一個(gè)自定義屏幕滑動(dòng)函數(shù)來(lái)幫我們解決屏幕滾動(dòng)問(wèn)題。
def gundong(driver, distance): #用于屏幕滾動(dòng) #測(cè)算出最大的距離根據(jù)電腦屏幕分辨率而異,一般填寫(xiě)400到800,800是最大滑動(dòng)距離 js = "var q=document.documentElement.scrollTop=" + str(distance) driver.execute_script(js) time.sleep(0.5)
(7)主函數(shù)
def zonghe(times): for i in range(0, times): # 初始配置,地址 url_survey = 'https://www.wjx.cn/vm/hiQpVeR.aspx' option = webdriver.ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option('useAutomationExtension', False) # 本地下載的谷歌瀏覽器地址 option.binary_location = r'D:\Goole_Local\Google\Chrome\Application\chrome.exe' # 下載好的Chrome驅(qū)動(dòng)的地址 driver = webdriver.Chrome(r"D:\Goole_Local\Google\Chrome\Application\chromedriver.exe", options=option) driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'}) # 啟動(dòng)要填寫(xiě)的地址 driver.get(url_survey) danxuan(driver) #調(diào)用單選函數(shù) duoxuan(driver) #調(diào)用多選函數(shù) gundong(driver, 600)#調(diào)用滾動(dòng)屏幕函數(shù),如果不需要?jiǎng)t注釋掉 #調(diào)用填空題函數(shù),這個(gè)3代表的意思是第三題是填空題,如果有其他填空題需要去完成再調(diào)用tiankong(driver, num)即可 #舉例:第八題也是填空題,這時(shí)我們加上tiankong(driver, 8) tiankong(driver, 3) # 最后交卷點(diǎn)擊提交 #time.slee()函數(shù)是表示延時(shí)的意思,里面可以放固定值也可以放隨機(jī)數(shù),這里我放的是隨機(jī)數(shù)。 time.sleep(random.randint(0, 1)) driver.find_element_by_css_selector('#ctlNext').click()#找到提交的css并點(diǎn)擊 time.sleep(4) renzheng(driver)#智能認(rèn)證函數(shù)調(diào)用 huakuai()#滑塊函數(shù)調(diào)用 print('已經(jīng)提交了{(lán)}次問(wèn)卷'.format(int(i) + int(1))) time.sleep(4) driver.quit()#停止
三、項(xiàng)目整體代碼
from selenium.webdriver.common.by import By # 沒(méi)有selenium庫(kù)的(請(qǐng)?jiān)谒玫沫h(huán)境下pip install selenium) from selenium import webdriver #selenium庫(kù) import random # 用于產(chǎn)生隨機(jī)數(shù) import time # 用于延時(shí) import pyautogui # 用于模擬人手 def gundong(driver, distance): #延時(shí)+屏幕滾動(dòng) js = "var q=document.documentElement.scrollTop=" + str(distance) #下拉像素(800是基于最頂端測(cè)算的距離) driver.execute_script(js) time.sleep(0.5) def danxuan(driver): # 找到所有標(biāo)簽(定位問(wèn)題)這里是單選 dan = driver.find_elements_by_css_selector('#div1 > div.ui-controlgroup.column1') for answer in dan: ans = answer.find_elements_by_css_selector('.ui-radio')#對(duì)應(yīng)的絕對(duì)子標(biāo)簽 random.choice(ans).click() # 找到標(biāo)簽并點(diǎn)擊 time.sleep(random.randint(0, 1)) def duoxuan(driver): #這里是多選題,找到所有多選的標(biāo)簽 duo = driver.find_elements_by_css_selector('#div2 > div.ui-controlgroup.column1') for answer in duo: ans = answer.find_elements_by_css_selector('.ui-checkbox')#對(duì)應(yīng)的絕對(duì)子標(biāo)簽 #隨機(jī)填幾次 for i in range(1, 7):#這里的7可以改成5,10,12 random.choice(ans).click()#找到標(biāo)簽并點(diǎn)擊 time.sleep(random.randint(0, 1)) def tiankong(driver, num): #填空函數(shù) #這里是所需要問(wèn)題的標(biāo)簽匯總,例如有四個(gè)要答的問(wèn)題,下面的answer的ABC數(shù)量需要跟index里面的數(shù)量相等 index = ["A", "B", "C"] # 自定義要回答的答案 answer = {"A": "python真的好用!", "B": "這個(gè)測(cè)試很成功!", "C": "填空題隨機(jī)填寫(xiě)文本"} driver.find_element(by=By.CSS_SELECTOR, value=f'#q{num}')\ .send_keys(answer.get(index[random.randint(0, len(index)-1)])) def renzheng(driver): # 智能驗(yàn)證,找到智能認(rèn)證的標(biāo)簽 bth = driver.find_element_by_css_selector( '#layui-layer1 > div.layui-layer-btn.layui-layer-btn- > a.layui-layer-btn0') bth.click()#點(diǎn)擊 time.sleep(1) rectBottom = driver.find_element_by_css_selector('#rectBottom') #提交按鈕 rectBottom.click() #點(diǎn)擊 time.sleep(5) def huakuai(): # 當(dāng)次數(shù)多了的時(shí)候就會(huì)出現(xiàn)滑塊,這里是模擬人手解決滑塊拖動(dòng) pyautogui.moveTo(random.randint(494, 496), 791, 0.2)#控制鼠標(biāo)移動(dòng)到x,y處,耗時(shí)0.2秒 time.sleep(1) pyautogui.dragTo(random.randint(888, 890), 791, 1)#讓鼠標(biāo)點(diǎn)擊并拖拽到x,y處,耗時(shí)1秒 time.sleep(1) pyautogui.click(random.randint(652, 667), random.randint(793, 795))#讓鼠標(biāo)點(diǎn)擊x,y處 time.sleep(1) pyautogui.moveTo(random.randint(494, 496), 791, 0.2)#控制鼠標(biāo)移動(dòng)到x,y處,耗時(shí)0.2秒 time.sleep(1) pyautogui.dragTo(random.randint(888, 890), 791, 1)#讓鼠標(biāo)點(diǎn)擊并拖拽到x,y處,耗時(shí)1秒 def zonghe(times): for i in range(0, times): # 初始配置,地址 url_survey = 'https://www.wjx.cn/vm/hiQpVeR.aspx' option = webdriver.ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option('useAutomationExtension', False) # 本地下載的谷歌瀏覽器地址 option.binary_location = r'D:\Goole_Local\Google\Chrome\Application\chrome.exe' # 下載好的Chrome驅(qū)動(dòng)的地址 driver = webdriver.Chrome(r"D:\Goole_Local\Google\Chrome\Application\chromedriver.exe", options=option) driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'}) # 啟動(dòng)要填寫(xiě)的地址 driver.get(url_survey) danxuan(driver) #調(diào)用單選函數(shù) duoxuan(driver) #調(diào)用多選函數(shù) gundong(driver, 600)#調(diào)用滾動(dòng)屏幕函數(shù),如果不需要?jiǎng)t注釋掉 tiankong(driver, 3)#調(diào)用填空題函數(shù) # 最后交卷點(diǎn)擊提交 time.sleep(random.randint(0, 1)) driver.find_element_by_css_selector('#ctlNext').click()#找到提交的css并點(diǎn)擊 time.sleep(4) renzheng(driver)#智能認(rèn)證函數(shù)調(diào)用 huakuai()#滑塊函數(shù)調(diào)用 print('已經(jīng)提交了{(lán)}次問(wèn)卷'.format(int(i) + int(1))) time.sleep(4) driver.quit()#停止 if __name__ == "__main__": zonghe(2)#里面填寫(xiě)的數(shù)是表示要提交多少次問(wèn)卷
四、項(xiàng)目修改及擴(kuò)展
如果上面的代碼發(fā)現(xiàn)跟自己?jiǎn)柧硇菍?duì)不上且無(wú)法打開(kāi)怎么辦,別慌!這里教你怎么修改代碼
①這里我們用谷歌瀏覽器打開(kāi)所需要填寫(xiě)的問(wèn)卷星地址,然后用電腦上的F12打開(kāi)開(kāi)發(fā)者模式
②這里我們可以選用快捷鍵CTRL+SHIFT+C啟動(dòng)元素檢查或者點(diǎn)擊我下圖標(biāo)注的地方來(lái)進(jìn)行選擇到題號(hào)
③然后我們?cè)俨榭催x擇題項(xiàng)的位置在哪里,然后我們就可以知道地方,再選擇復(fù)制CSS地址就可以得到要修改的地方了
④復(fù)制完之后我們可以看到得到的是什么,這里得到的就是單選題的大標(biāo)簽
#div1 > div.ui-controlgroup.column1
再接著我們就可以看到各個(gè)小標(biāo)簽
⑤然后我們就可以修改我們的代碼了
def danxuan(driver): ''' 找到所有標(biāo)簽(定位問(wèn)題)這里是單選,注意我們使用的是find.elements_by_CSS_selector() 這樣得到的是一個(gè)列表,里面包含了所有的選擇題,將我們得到的大標(biāo)簽填入如下 再修改我們所需要選擇的小標(biāo)簽,注意小標(biāo)簽填寫(xiě)的時(shí)候前面要加 .(點(diǎn),如:.ui-radio) 這是代表選擇題的絕對(duì)路徑,這樣選擇單選的時(shí)候就不會(huì)錯(cuò)誤。 ''' dan = driver.find_elements_by_css_selector('#div1 > div.ui-controlgroup.column1') for answer in dan: ans = answer.find_elements_by_css_selector('.ui-radio')#對(duì)應(yīng)的絕對(duì)子標(biāo)簽 random.choice(ans).click() # 找到標(biāo)簽并點(diǎn)擊 time.sleep(random.randint(0, 1))
多選題和填空題也是一樣,看代碼相信大家一定能看懂,這里就不過(guò)多展示了
這里用的是CSS的方式,其實(shí)在項(xiàng)目中可以選擇ID查找,XPATH路徑去查找都可以,博客里面也有很多資料,都萬(wàn)變不離其宗,找到對(duì)應(yīng)的標(biāo)簽即可。
driver.find_element_by_xpath('//*[@id="div1"]/div[2]/div[1]') 這是用XPATH得到的 簡(jiǎn)單解釋一下里面的值含義吧 //*[@id="div1"]/div[2]/div[1] 第一個(gè)div1表示的是第一題,第二個(gè)div[2]表示的是第二大部分是選擇題,第三個(gè)div[1]表示的是選擇第一個(gè)。 那么你一定能看懂這個(gè)XPATH是什么意思 //*[@id="div2"]/div[2]/div[2] 這里表示的是第二題選擇題第二個(gè)。
五、總結(jié)
python的selenium庫(kù)是個(gè)很重要的網(wǎng)頁(yè)處理函數(shù)庫(kù),在處理動(dòng)態(tài)網(wǎng)頁(yè)上扮演者很重要的角色,一般我們所看到的網(wǎng)頁(yè)都可以用里面對(duì)應(yīng)方法來(lái)完成,只要理解到標(biāo)簽的含義,其實(shí)做這類的題是很簡(jiǎn)單的,這里就是想起前面那段時(shí)間填寫(xiě)問(wèn)卷的時(shí)候,所以有感寫(xiě)下這篇文章和方法,但是實(shí)際上如果是去比賽的做市場(chǎng)調(diào)研之類的,還是不要用這種方式,畢竟真人的感覺(jué)選擇和機(jī)器的隨機(jī)選擇出入還是很大的,在信度分析和效度分析很可能就會(huì)垮掉
到此這篇關(guān)于利用Python實(shí)現(xiàn)問(wèn)卷星自動(dòng)填寫(xiě)的文章就介紹到這了,更多相關(guān)Python實(shí)現(xiàn)問(wèn)卷星自動(dòng)填寫(xiě)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python生成以及打開(kāi)json、csv和txt文件的實(shí)例
今天小編就為大家分享一篇python生成以及打開(kāi)json、csv和txt文件的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11selenium+python實(shí)現(xiàn)1688網(wǎng)站驗(yàn)證碼圖片的截取功能
這篇文章主要介紹了selenium+python實(shí)現(xiàn)1688網(wǎng)站驗(yàn)證碼圖片的截取,需要的朋友可以參考下2018-08-08Python實(shí)現(xiàn)excel轉(zhuǎn)sqlite的方法
這篇文章主要介紹了Python實(shí)現(xiàn)excel轉(zhuǎn)sqlite的方法,結(jié)合實(shí)例形式分析了Python基于第三方庫(kù)xlrd讀取Excel文件及寫(xiě)入sqlite的相關(guān)操作技巧,需要的朋友可以參考下2017-07-07pyv8學(xué)習(xí)python和javascript變量進(jìn)行交互
這篇文章主要介紹了pyv8學(xué)習(xí)python和javascript變量進(jìn)行交互,python取得javascript里面的值、javascript取得python里面的值、python和javascript里面的函數(shù)交互2013-12-12