日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python实现刷问卷星份数(面向对象)

發布時間:2023/12/14 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现刷问卷星份数(面向对象) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、前言

二、模塊準備

①Sojump.py需要的模塊/包

②具體問卷.py需要的模塊/包

三、具體代碼講解

3.1? Sojump.py

功能1 計數器counter()

功能2 偽裝selenium

更新知識 selenium的更新

01 danxuan()→單選題(隨機選擇)

02 fixed_danxuan()→單選題(只選擇某個選項)

03 excluded_danxuan()→單選題(排除一個或一些選項)

04 range_danxuan()→單選題(在m到n范圍內單選)

05 restrictive_danxuan()→單選題(在某些選項中選擇)

06 textinput_danxuan()→單選題(選項中允許填空)

07 duoxuan()→多選題(隨機選擇)

08 fixed_duoxuan()→多選題(只選擇某些選項)

09?excluded_duoxuan()→多選題(排除一個或一些選項)

10 restrictive_duoxuan()→多選題(在某些選項中多選)

11?range_duoxuan()→多選題(在m到n范圍內的多選)

12?textinput_duoxuan()→多選題(選項中允許填空)

13?text()→文本題

隨機所在城市的選擇? random_city_selection()

限制所在城市的選擇? restrictive_city_selection()

提交按鈕? submit()

★全部代碼展示★

3.2? 具體問卷.py

★全部代碼展示★

具體代碼講解

四、總結


一、前言

? ? ? ? 筆者之前也寫過python實現問卷星刷份數的代碼與文章(如下)

隔壁寢室刷問卷刷瘋了https://blog.csdn.net/knighthood2001/article/details/120175929?spm=1001.2014.3001.5502python自動化------問卷星刷問卷3.0版本https://blog.csdn.net/knighthood2001/article/details/120175929?spm=1001.2014.3001.5502? ? ? ?

????????不過之前寫的屬于面向過程版本,它有很大的局限性,即根據不同的問卷需要按照邏輯步驟寫相應的代碼,代碼量非常繁瑣,并且很多代碼都是重復的,因此如果后續查看與更改起來也非麻煩;此外,由于距離上一次寫關于問卷星的時間較長,問卷星頁面元素定位可能發生了更改,需要重新獲取相應的元素定位,如xpath、css selector;再加上由于selenium的升級,之前定位元素的方法被棄用,需要改變之前寫的代碼。

????????以上三個原因,使得筆者重新對之前的代碼進行增刪改查,最終將之前的面向過程版本寫成了面向對象版本。通過將一個個的功能封裝成函數,在使用時只需要調用即可。代碼量大大降低,且無需重復造車輪,對于后續檢查與更改來說也比較輕松。

二、模塊準備

????????首先創建兩個python文件,Sojump的翻譯就是問卷星,通過在Sojump.py文件中編寫主要函數,在具體問卷.py文件中通過導入Sojump,在編寫該問卷的代碼,最終實現刷份數。

①Sojump.py需要的模塊/包

import random from selenium import webdriver import time from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select

②具體問卷.py需要的模塊/包

import random import Sojump from Sojump import Wenjuanxing import schedule as schedule

三、具體代碼講解

3.1? Sojump.py

!這里的內容是重中之重!

①元素定位分析

xpath

//*[@id="divquestion1"]/ul/li[1]

? ? ? ? 上述表示的是問卷星問卷第一題的第1個選項

//*[@id="divquestion1"]/ul/li[2]

? ? ? ? 上述表示的是問卷星問卷第一題的第2個選項

????????經觀察,可以得出問卷星問題的通用xpath,如下

# 選項的xpath base_xpaths = '//*[@id="divquestion{}"]/ul/li'

css_selector?

????????大致思路同上,得到問卷星選項的通用css_selector,如下

# 選項的css_selector base_css_selectors = '#divquestion{} > ul > li:nth-child({})'

允許填空選項的css_selector?

????????有些問題的選項允許填空,其通用css_selector?如下

# 允許填空選項的css_selector input_css_selectors = '#divquestion{} > ul > li:nth-child({}) > input.underline'

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!注意:筆者發現問卷星有兩類問卷,其對應的元素定位有所不同。

具體區分如下(筆者也是在寫完該文章后突然發現,大家可以自行去試試你的問卷元素定位屬于哪一類,第二種由于沒有相應的問卷,可能xpath和css_selector定位會發生錯誤,不過這不是重點,大家只需找到并更改即可)

如果大家發現無法刷問卷,可能就是元素定位出現了問題?

'''適用的可能是問卷星網頁無法右鍵,只能通過F12或者 ctrl+shift+i快捷鍵進入開發者工具的問卷,并且打開開發者工具后會顯示已在調試程序中暫停''' # 選項的xpath base_xpaths = '//*[@id="divquestion{}"]/ul/li' # 選項的css_selector base_css_selectors = '#divquestion{} > ul > li:nth-child({})' # 允許填空選項的css_selector input_css_selectors = '#divquestion{} > ul > li:nth-child({}) > input.underline''''適用的可能是除了上面的情況的問卷星''' # 選項的xpath base_xpaths = '//*[@id="div{}"]/div/div' # 選項的css_selector base_css_selectors = 'div{} > div.ui-controlgroup.column{} > div.ui-checkbox.checked' # 允許填空選項的css_selector input_css_selectors = 'tqq{}_{}'

②創建類并初始化

class Wenjuanxing(object):# 初始化def __init__(self, url):self.url = url

????????創建一個Wenjuanxing()的類,并初始化url


接下來就開始編寫函數了

功能1 計數器counter()

在類外面先定義一個count=0,然后使用下面的counter()函數,用以計數是第幾次運行代碼,刷了幾次問卷。

# 計數器def counter(self):global countcount += 1w = print("第{}次運行".format(count))return w

功能2 偽裝selenium

????????需要進行偽裝的原因:筆者發現是因為問卷星的網頁有反爬機制,它會檢查你是不是通過selenium訪問網頁的。大多數情況下,檢測基本原理是檢測當前瀏覽器窗口下的window.navigator對象是否包含webdriver這個屬性。因為在正常使用瀏覽器的情況下,這個屬性是undefined,然而一旦我們使用了selenium,selenium會給window.navigator設置webdriver屬性。很多網站就通過JS判斷如果webdrive 屬性存在,那就直接屏蔽。以下代碼可以在每次頁面加載之前就不會給window.navigator設置webdriver屬性,從而能夠通過智能檢測。

詳情可以看筆者寫的之前的文章

隔壁寢室刷問卷刷瘋了https://blog.csdn.net/knighthood2001/article/details/120175929?spm=1001.2014.3001.5502

# 偽裝seleniumdef weizhuang_selenium(self):# 躲避智能檢測self.option = webdriver.ChromeOptions()self.option.add_experimental_option('excludeSwitches', ['enable-automation'])self.option.add_experimental_option('useAutomationExtension', False)self.driver = webdriver.Chrome(options=self.option)self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})self.driver.get(self.url)

更新知識 selenium的更新

? ? ? ? chromedriver的知識我就不細說了,主要講的是selenium更新后,元素定位的方法發生改變。

以前:

????????模塊

from selenium import webdriver

????????定位元素方法?

# 1、通過ID進行定位 find_element_by_id('id') # 2、通過名字進行定位 find_element_by_name('name') # 3、通過類名進行元素定位 find_elements_by_class_name('class_name') # 4、通過元素標簽屬性 find_element_by_tag_name('tag_name') # 5、 通過頁面文本信息 find_element_by_link_text('link_text') # 6、通過模糊文本信息 find_element_by_partial_link_text('partial_link_text') # 7、通過查找元素路徑 find_element_by_xpath('xpath') # 8、通過頁面上的css元素進行定位 find_element_by_css_selector('css_selector')

更新后:

????????需要在導入一個模塊

from selenium import webdriver from selenium.webdriver.common.by import By

????????定位元素方法?

driver.find_element(by=By.ID, value='ID') driver.find_element(by=By.NAME, value='NAME') driver.find_element(by=By.CLASS_NAME, value='CLASS_NAME') driver.find_element(by=By.TAG_NAME, value='TAG_NAME') driver.find_element(by=By.LINK_TEXT, value='LINK_TEXT') driver.find_element(by=By.PARTIAL_LINK_TEXT, value='PARTIAL_LINK_TEXT') driver.find_element(by=By.XPATH, value='XPATH') driver.find_element(by=By.CSS_SELECTOR, value='CSS_SELECTOR')

01 danxuan()→單選題(隨機選擇)

# 01 單選題(隨機選擇)def danxuan(self, i):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = random.randint(1, len(a))self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()

講解:i表示題號

首先使用全局變量并通過format(i)函數給出具體的題號

a表示定位題目所對應的選項

len(a)表示題目所對應的選項個數

b表示隨機生成選項個數以內的一個數

最后定位該選項并點擊,完成隨機選擇
?

self.driver.find_element(by=By.CSS_SELECTOR,value='#divquestion{} > ul > li:nth-child({}) > label'.format(i, b)).click()

注意:在上面的代碼,由于筆者在之前的文章中使用過xpath定位,不過出現了定位不到的現象,所以我使用css_selector進行定位元素。



02 fixed_danxuan()→單選題(只選擇某個選項)

# 02 單選題(只選擇某個選項)def fixed_danxuan(self, i, b):self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()

講解:b表示需要選擇的選項在該題目選項中的位置

03 excluded_danxuan()→單選題(排除一個或一些選項)

# 03 單選題(排除一個或一些選項)def excluded_danxuan(self, i, *args):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)c = []# y是計算arg的個數,方便計算還剩幾個選項y = 0for x in range(1, len(a) + 1):c.append(x)for arg in args:y += 1c.remove(arg)d = random.choice(c)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, d)).click()

思路:是創建一個列表c,然后將選項個數添加進列表,之后根據輸入的變量,在列表中逐個去除,最終在剩下的列表中隨機選擇一個,進行定位與點擊。

04 range_danxuan()→單選題(在m到n范圍內單選)

# 04 單選題(在m到n范圍內單選)def range_danxuan(self, i, m, n):x = random.randint(m, n)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, x)).click()

思路:是用random.randint(m,n)函數返回一個m到n范圍內的隨機整數

05 restrictive_danxuan()→單選題(在某些選項中選擇)

# 05 單選題(在某些選項中選擇)如6個選項,在1235中單選def restrictive_danxuan(self, i, *args):m = []for arg in args:m.append(arg)n = random.choice(m)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, n)).click()

思路:將所輸入的參數存入到列表中,然后使用random.choice()函數隨機選擇其中的一個數

06 textinput_danxuan()→單選題(選項中允許填空)

# 06 單選題(選項中允許填空)def textinput_danxuan(self, i, c, wenzi):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = random.randint(1, len(a))self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()if c == b:time.sleep(0.2)self.driver.find_element(by=By.CSS_SELECTOR,value=input_css_selectors.format(i, c)).send_keys(wenzi)

?思路:首先選擇某個選項,如果該選項和自己輸入的c相同,即可再輸入文字。

07 duoxuan()→多選題(隨機選擇)

# 07 多選題(隨機選擇)def duoxuan(self, i):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = len(a)# m中存放選項m = []for x in range(1, b + 1):m.append(x)c = random.randint(1, b)n = random.sample(m, c)for o in n:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, o)).click()

思路:列表m中存放選項;c表示隨機生成一個選項以內的數字,即多選題要選擇選項的個數;n表示從列表m中隨機選擇c個個數,返回類型為列表,然后經過遍歷,實現多選題的多個選項的選擇。

08 fixed_duoxuan()→多選題(只選擇某些選項)

# 08 多選題(只選擇某些選項)def fixed_duoxuan(self, i, *args):for arg in args:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, arg)).click()

09?excluded_duoxuan()→多選題(排除一個或一些選項)

# 09 多選題(排除一個或一些的選項)def excluded_duoxuan(self, i, *args):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)# print(len(a))c = []# y是計算arg的個數,方便計算還剩幾個選項y = 0for x in range(1, len(a)+1):c.append(x)for arg in args:y += 1c.remove(arg)# 還剩下幾個選項z = len(a) - y# 多選題選項個數b = random.randint(1, z)# 多選題用sample()d = random.sample(c, b)for r in d:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()

思路:列表c中存放選項個數,然后逐一刪除輸入的參數,然后在剩下的選項中用多選題的思路進行操作。?

10 restrictive_duoxuan()→多選題(在某些選項中多選)

# 10 多選題(在某些選項中多選)def restrictive_duoxuan(self, i, *args):m = []for arg in args:m.append(arg)n = random.randint(1, len(m))o = random.sample(m, n)for q in o:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, q)).click()

思路:列表m中存放的內容就是所輸入的參數,?然后用多選題的思路進行操作。

11?range_duoxuan()→多選題(在m到n范圍內的多選)

# 11 多選題(在m到n范圍內的多選)def range_duoxuan(self, i, m, n):# 列表c為m到n的選項組,如當m=2,n=5時,c=[2,3,4,5]c = []for x in range(m, n+1):c.append(x)# 選項個數o = n - m + 1# 隨機生成要填幾個選項p = random.randint(1, o)d = random.sample(c, p)for r in d:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()

?思路:列表c為m到n的選項組,如當m=2,n=5時,c=[2,3,4,5],然后用多選題的思路進行操作。

12?textinput_duoxuan()→多選題(選項中允許填空)

# 12 多選題(選項中允許填空)def textinput_duoxuan(self, i, c, wenzi):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = len(a)# m中存放選項m = []for x in range(1, b + 1):m.append(x)# 隨機生成要多選的選項個數o = random.randint(1, b)# 在選項中隨機選取o個選項n = random.sample(m, o)for r in n:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()if c == r:time.sleep(0.2)self.driver.find_element(by=By.CSS_SELECTOR,value=input_css_selectors.format(i, c)).send_keys(wenzi)

注意:該函數只適用于一個選項中需要文本輸入的多選題。

思路:查看? 06 單選題(選項中允許填空)和??07 多選題(隨機選擇)? 即可理解。

13?text()→文本題

# 13 文本題def text(self, i, wenzi):self.driver.find_element(by=By.CSS_SELECTOR, value='#q{}'.format(i)).send_keys(wenzi)

思路:通過wenzi參數填寫相應的內容,實現文字題的填寫。

隨機所在城市的選擇? random_city_selection()

?

?請選擇您所在的城市的題目如上

?

????????如上圖所示, 問卷星還給出了海外這個選項,不過一般用不到,所以筆者就除去了它,剩下的列表并存在provinces中,之后用random函數即可隨機選擇城市。

????????將它存到自制的列表還有一個原因就是selenium的Select提供的三種選擇方式select_by_index(index)、select_by_value(value)、select_by_visible_text(visible_text),問卷星中只給出了value,因此很難隨機選擇。例如:如果給出index,那我們就可以使用random函數進行隨機選擇。

provinces = ['北京', '天津', '河北', '山西', '內蒙古', '遼寧', '吉林', '黑龍江','上海', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南','湖北', '湖南', '廣東', '廣西', '海南', '重慶', '四川', '貴州','云南', '西藏', '陜西', '甘肅', '青海', '寧夏', '新疆', '臺灣','香港', '澳門']

?

注意:

①上圖中,省份與城市的選擇頁面是寫在ifame中,?因此需要進行frame和iframe之間的切換。關鍵不要忘記切換回去。如果沒有切換回去,即使點擊確定鍵后,它仍在iframe中,會使得接下來元素定位失敗。

②a表示省/直轄市下的城市。

# 隨機所在城市的選擇def random_city_selection(self, i):frame = self.driver.find_element(by=By.XPATH, value='//*[@id="q{}"]'.format(i))frame.click()# 滾動到最底端# self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")self.driver.switch_to.frame('PDF_i_chezchenz')ele = self.driver.find_element(by=By.CSS_SELECTOR, value='#province')s = Select(ele)province = random.choice(provinces)s.select_by_value(province)a = self.driver.find_elements(by=By.XPATH, value='//*[@id="city"]/label')# len(a)表示省下的城市有幾個# print(len(a))b = random.randint(1, len(a))self.driver.find_element(by=By.XPATH, value='//*[@id="city"]/label[{}]'.format(b)).click()self.driver.find_element(by=By.XPATH, value='//*[@id="form1"]/div[3]/div/input').click()# 注意切換回原來的frameself.driver.switch_to.parent_frame()

限制所在城市的選擇? restrictive_city_selection()

# 限制所在城市的選擇def restrictive_city_selection(self, i, arg):frame = self.driver.find_element(by=By.XPATH, value='//*[@id="q{}"]'.format(i))frame.click()# 滾動到最底端# self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")self.driver.switch_to.frame('PDF_i_chezchenz')ele = self.driver.find_element(by=By.CSS_SELECTOR, value='#province')s = Select(ele)s.select_by_value(arg)a = self.driver.find_elements(by=By.XPATH, value='//*[@id="city"]/label')# len(a)表示省下的城市有幾個# print(len(a))b = random.randint(1, len(a))self.driver.find_element(by=By.XPATH, value='//*[@id="city"]/label[{}]'.format(b)).click()self.driver.find_element(by=By.XPATH, value='//*[@id="form1"]/div[3]/div/input').click()# 注意切換回原來的frameself.driver.switch_to.parent_frame()

????????以上代碼與隨機所在城市的選擇的差別主要在于,添加了一個不定參數arg

通過在具體問卷.py文件中創立一個具有幾個城市的列表,然后隨機選擇它并將其作為arg參數,實現隨機選擇你所需要的城市。

例如下面的代碼:

????????具體問卷.py

restrictive_provinces = ['云南', '貴州', '四川'] restrictive_province = random.choice(restrictive_provinces)

提交按鈕? submit()

?

上圖所示的就是提交按鈕的流程?

按步驟寫代碼,如下

注意:有些步驟需要一點時間,所以加上time.sleep()

# 提交按鈕def submit(self):# time.sleep(0.5)btn = self.driver.find_element(by=By.CSS_SELECTOR, value='#submit_button')btn.click()# 出現點擊驗證碼驗證time.sleep(1)self.driver.find_element(by=By.XPATH, value='//*[@id="alert_box"]/div[2]/div[2]/div[2]/button').click()time.sleep(0.5)self.driver.find_element(by=By.XPATH, value='//*[@id="SM_BTN_1"]').click()time.sleep(4)# 關閉頁面handles = self.driver.window_handlesself.driver.switch_to.window(handles[0])# time.sleep(0.5)# # 刷新頁面(可能不需要)# self.driver.refresh()# 關閉當前頁面,如果只有一個頁面,則也關閉瀏覽器self.driver.close()

以上就是Sojump.py的全部代碼講解


全部代碼展示

# -*- coding: utf-8-*- import random from selenium import webdriver import time from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select""" 01 單選題(隨機選擇)danxuan() 02 單選題(只選擇某個選項)fixed_danxuan() 03 單選題(排除一個或一些選項)excluded_danxuan() 04 單選題(在m到n范圍內單選)range_danxuan() 05 單選題(在某些選項中選擇)如6個選項,在1235中單選restrictive_danxuan() 06 單選題(選項中允許填空)textinput_danxuan() 07 多選題(隨機選擇)duoxuan() 08 多選題(只選擇某些選項)fixed_duoxuan() 09 多選題(排除一個或一些選項)excluded_duoxuan() 10 多選題(在某些選項中多選)restrictive_duoxuan() 11 多選題(在m到n范圍內的多選)range_duoxuan() 12 多選題(選項中允許填空)text_input_duoxuan() 13 文本題text() """ count = 0 provinces = ['北京', '天津', '河北', '山西', '內蒙古', '遼寧', '吉林', '黑龍江','上海', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南','湖北', '湖南', '廣東', '廣西', '海南', '重慶', '四川', '貴州','云南', '西藏', '陜西', '甘肅', '青海', '寧夏', '新疆', '臺灣','香港', '澳門']'''適用的可能是問卷星網頁無法右鍵,只能通過F12或者ctrl+shift+i快捷鍵進入開發者工具的問卷''' # 選項的xpath base_xpaths = '//*[@id="divquestion{}"]/ul/li' # 選項的css base_css_selectors = '#divquestion{} > ul > li:nth-child({})' # 允許填空選項的css_selector input_css_selectors = '#divquestion{} > ul > li:nth-child({}) > input.underline''''適用的可能是除了上面的情況的問卷星''' # 選項的xpath # base_xpaths = '//*[@id="div{}"]/div/div' # 選項的css # base_css_selectors = 'div{} > div.ui-controlgroup.column{} > div.ui-checkbox.checked' # 允許填空選項的css_selector # input_css_selectors = 'tqq{}_{}'class Wenjuanxing(object):# 初始化def __init__(self, url):self.url = url# 計數器def counter(self):global countcount += 1w = print("第{}次運行".format(count))return w# 偽裝seleniumdef weizhuang_selenium(self):# 躲避智能檢測self.option = webdriver.ChromeOptions()self.option.add_experimental_option('excludeSwitches', ['enable-automation'])self.option.add_experimental_option('useAutomationExtension', False)self.driver = webdriver.Chrome(options=self.option)self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})self.driver.get(self.url)# 01 單選題(隨機選擇)def danxuan(self, i):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = random.randint(1, len(a))self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()# 02 單選題(只選擇某個選項)def fixed_danxuan(self, i, b):self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()# 03 單選題(排除一個或一些選項)def excluded_danxuan(self, i, *args):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)c = []# y是計算arg的個數,方便計算還剩幾個選項y = 0for x in range(1, len(a) + 1):c.append(x)for arg in args:y += 1c.remove(arg)d = random.choice(c)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, d)).click()# 04 單選題(在m到n范圍內單選)def range_danxuan(self, i, m, n):x = random.randint(m, n)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, x)).click()# 05 單選題(在某些選項中選擇)如6個選項,在1235中單選def restrictive_danxuan(self, i, *args):m = []for arg in args:m.append(arg)n = random.choice(m)self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, n)).click()# 06 單選題(選項中允許填空)def textinput_danxuan(self, i, c, wenzi):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = random.randint(1, len(a))self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, b)).click()if c == b:time.sleep(0.2)self.driver.find_element(by=By.CSS_SELECTOR,value=input_css_selectors.format(i, c)).send_keys(wenzi)# 07 多選題(隨機選擇)def duoxuan(self, i):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = len(a)# m中存放選項m = []for x in range(1, b + 1):m.append(x)c = random.randint(1, b)n = random.sample(m, c)for o in n:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, o)).click()# 08 多選題(只選擇某些選項)def fixed_duoxuan(self, i, *args):for arg in args:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, arg)).click()# 09 多選題(排除一個或一些的選項)def excluded_duoxuan(self, i, *args):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)# print(len(a))c = []# y是計算arg的個數,方便計算還剩幾個選項y = 0for x in range(1, len(a)+1):c.append(x)for arg in args:y += 1c.remove(arg)# 還剩下幾個選項z = len(a) - y# 多選題選項個數b = random.randint(1, z)# 多選題用sample()d = random.sample(c, b)for r in d:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()# 10 多選題(在某些選項中多選)def restrictive_duoxuan(self, i, *args):m = []for arg in args:m.append(arg)n = random.randint(1, len(m))o = random.sample(m, n)for q in o:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, q)).click()# 11 多選題(在m到n范圍內的多選)def range_duoxuan(self, i, m, n):# 列表c為m到n的選項組,如當m=2,n=5時,c=[2,3,4,5]c = []for x in range(m, n+1):c.append(x)# 選項個數o = n - m + 1# 隨機生成要填幾個選項p = random.randint(1, o)d = random.sample(c, p)for r in d:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()# 12 多選題(選項中允許填空)def text_input_duoxuan(self, i, c, wenzi):global base_xpathsbase_xpath = base_xpaths.format(i)a = self.driver.find_elements(by=By.XPATH, value=base_xpath)b = len(a)# m中存放選項m = []for x in range(1, b + 1):m.append(x)# 隨機生成要多選的選項個數o = random.randint(1, b)# 在選項中隨機選取o個選項n = random.sample(m, o)for r in n:self.driver.find_element(by=By.CSS_SELECTOR,value=base_css_selectors.format(i, r)).click()if c == r:time.sleep(0.2)self.driver.find_element(by=By.CSS_SELECTOR,value=input_css_selectors.format(i, c)).send_keys(wenzi)# 13 文本題def text(self, i, wenzi):self.driver.find_element(by=By.CSS_SELECTOR, value='#q{}'.format(i)).send_keys(wenzi)# 隨機所在城市的選擇def random_city_selection(self, i):frame = self.driver.find_element(by=By.XPATH, value='//*[@id="q{}"]'.format(i))frame.click()# 滾動到最底端self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")self.driver.switch_to.frame('PDF_i_chezchenz')ele = self.driver.find_element(by=By.CSS_SELECTOR, value='#province')s = Select(ele)province = random.choice(provinces)s.select_by_value(province)a = self.driver.find_elements(by=By.XPATH, value='//*[@id="city"]/label')# len(a)表示省下的城市有幾個# print(len(a))b = random.randint(1, len(a))self.driver.find_element(by=By.XPATH, value='//*[@id="city"]/label[{}]'.format(b)).click()self.driver.find_element(by=By.XPATH, value='//*[@id="form1"]/div[3]/div/input').click()# 注意切換回原來的frameself.driver.switch_to.parent_frame()# 限制所在城市的選擇def restrictive_city_selection(self, i, arg):frame = self.driver.find_element(by=By.XPATH, value='//*[@id="q{}"]'.format(i))frame.click()# 滾動到最底端# self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")self.driver.switch_to.frame('PDF_i_chezchenz')ele = self.driver.find_element(by=By.CSS_SELECTOR, value='#province')s = Select(ele)s.select_by_value(arg)a = self.driver.find_elements(by=By.XPATH, value='//*[@id="city"]/label')# len(a)表示省下的城市有幾個# print(len(a))b = random.randint(1, len(a))self.driver.find_element(by=By.XPATH, value='//*[@id="city"]/label[{}]'.format(b)).click()self.driver.find_element(by=By.XPATH, value='//*[@id="form1"]/div[3]/div/input').click()# 注意切換回原來的frameself.driver.switch_to.parent_frame()# 提交按鈕def submit(self):# time.sleep(0.5)btn = self.driver.find_element(by=By.CSS_SELECTOR, value='#submit_button')btn.click()# 出現點擊驗證碼驗證time.sleep(1)self.driver.find_element(by=By.XPATH, value='//*[@id="alert_box"]/div[2]/div[2]/div[2]/button').click()time.sleep(0.5)self.driver.find_element(by=By.XPATH, value='//*[@id="SM_BTN_1"]').click()time.sleep(4)# 關閉頁面handles = self.driver.window_handlesself.driver.switch_to.window(handles[0])# time.sleep(0.5)# # 刷新頁面(可能不需要)# self.driver.refresh()# 關閉當前頁面,如果只有一個頁面,則也關閉瀏覽器self.driver.close()

3.2? 具體問卷.py

由于問卷涉及一些內容,不便公開,因此我就將問卷內容馬賽克了(如下圖),網址也不公布了。大家了解一下題目的類型即可

★全部代碼展示★

# -*- coding: utf-8-*- import random import Sojump from Sojump import Wenjuanxing import schedule as schedulerestrictive_provinces = ['云南', '貴州', '四川']problems_10_1 = ['', 'xxx', 'xx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx']problems_10_2 = ['', 'xxx', 'xx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx']if __name__ == '__main__':url = '問卷星網址'wenjuanxing = Wenjuanxing(url)def run():# 隨機內容restrictive_province = random.choice(restrictive_provinces)problem_10_1 = random.choice(problems_10_1)problem_10_2 = random.choice(problems_10_2)# 計數器wenjuanxing.counter()# 偽裝seleniumwenjuanxing.weizhuang_selenium()# 問卷題目wenjuanxing.danxuan(1)wenjuanxing.danxuan(2)wenjuanxing.restrictive_danxuan(3, 2, 3, 4, 5)wenjuanxing.danxuan(4)wenjuanxing.danxuan(5)wenjuanxing.danxuan(6)wenjuanxing.duoxuan(7)wenjuanxing.danxuan(8)wenjuanxing.danxuan(9)# 第十題為兩個選項都可以填空的單選題,因此嘗試用try excepttry:wenjuanxing.textinput_danxuan(10, 1, problem_10_1)# print(problem_10_1)wenjuanxing.textinput_danxuan(10, 2, problem_10_2)# print(problem_10_2)except:passwenjuanxing.duoxuan(11)wenjuanxing.danxuan(12)# 13得考慮一下# 第13題雖然是有五個選項的多選題,不過依據邏輯,它只能分成1 3 1 形式,# 即要么選擇第一個選項,要么在中間三個選項之間進行多選,要么選擇最后一個選項。a = random.randint(1, 3)if a == 1:wenjuanxing.fixed_danxuan(13, 1)elif a == 2:wenjuanxing.range_duoxuan(13, 2, 5)else:wenjuanxing.fixed_danxuan(13, 6)wenjuanxing.danxuan(14)wenjuanxing.duoxuan(15)wenjuanxing.duoxuan(16)wenjuanxing.danxuan(17)# 限制省份的隨機選擇# print(restrictive_province)wenjuanxing.restrictive_city_selection(18, restrictive_province)# time.sleep(3)# 提交問卷wenjuanxing.submit()# 每隔2秒運行schedule.every(2).seconds.do(run)# 判斷條件while Sojump.count < 50:schedule.run_pending()

具體代碼講解

①每隔一段時間運行代碼

import schedule as schedule def run():passschedule.every(2).seconds.do(run)while True:schedule.run_pending()

???該模板請牢記,上述代碼表示每隔五秒運行一次,如果需要每隔一秒運行一次代碼,則將其中的

schedule.every(2).seconds.do(run)改為 schedule.every(1).second.do(run)

由于count參數表示代碼運行的次數,而問卷星在刷50份后得過一小時后才能繼續刷,因此得加個判斷(如下),防止程序一直運行。

while Sojump.count < 50:

②編寫主體代碼

? ? ? ? 因為一些題目的選項中需要填寫文本,以及如果大家需要限定省份的隨機隨機選擇。這就需要制作相應的列表,然后通過隨機選取列表中的某個內容,自動填寫進問卷。

restrictive_provinces = ['云南', '貴州', '四川']problems_10_1 = ['', 'xxx', 'xx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx']problems_10_2 = ['', 'xxx', 'xx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx', 'xxx']

這里需要注意的是:?隨機選取列表中內容的代碼段需要編寫在run()函數中而不能直接寫在上述代碼下面,否則不經過run()函數,不會進行每隔一段時間運行的過程,其產生的隨機內容將在每次使用都不變。這是筆者后來無意發現的,說來慚愧,這一個小失誤,導致一次刷的50份的文本內容都一樣,因此大家敲代碼時需要多思考。

????????接下來需要調用類

url = '問卷星網址' wenjuanxing = Wenjuanxing(url)

? ? ? ? 接下來就是編寫run()函數,其中主要就是根據問卷內容、題目類型的不同而編寫。

代碼如下:

def run():# 隨機內容restrictive_province = random.choice(restrictive_provinces)problem_10_1 = random.choice(problems_10_1)problem_10_2 = random.choice(problems_10_2)# 計數器wenjuanxing.counter()# 偽裝seleniumwenjuanxing.weizhuang_selenium()# 問卷題目wenjuanxing.danxuan(1)wenjuanxing.danxuan(2)wenjuanxing.restrictive_danxuan(3, 2, 3, 4, 5)wenjuanxing.danxuan(4)wenjuanxing.danxuan(5)wenjuanxing.danxuan(6)wenjuanxing.duoxuan(7)wenjuanxing.danxuan(8)wenjuanxing.danxuan(9)# 第十題為兩個選項都可以填空的單選題,因此嘗試用try excepttry:wenjuanxing.textinput_danxuan(10, 1, problem_10_1)# print(problem_10_1)wenjuanxing.textinput_danxuan(10, 2, problem_10_2)# print(problem_10_2)except:passwenjuanxing.duoxuan(11)wenjuanxing.danxuan(12)# 13得考慮一下# 第13題雖然是有五個選項的多選題,不過依據邏輯,它只能分成1 3 1 形式,# 即要么選擇第一個選項,要么在中間三個選項之間進行多選,要么選擇最后一個選項。a = random.randint(1, 3)if a == 1:wenjuanxing.fixed_danxuan(13, 1)elif a == 2:wenjuanxing.range_duoxuan(13, 2, 5)else:wenjuanxing.fixed_danxuan(13, 6)wenjuanxing.danxuan(14)wenjuanxing.duoxuan(15)wenjuanxing.duoxuan(16)wenjuanxing.danxuan(17)# 限制省份的隨機選擇# print(restrictive_province)wenjuanxing.restrictive_city_selection(18, restrictive_province)# time.sleep(3)# 提交問卷wenjuanxing.submit()

????????著重注意一下以下兩題

第10題為兩個選項都可以填空的單選題,因此嘗試用try except。 第13題雖然是有五個選項的多選題,不過依據邏輯,它只能分成1 3 1 形式, 即要么選擇第一個選項,要么在中間三個選項之間進行多選,要么選擇最后一個選項。

此外,如果要進行隨機省份的選擇,只需調用即可(如下)

wenjuanxing.random_city_selection(18)

剩下的其他函數在之前的內容中講過,也比較簡單。?


四、總結

????????問卷星根據題目的不同、題目和選項的搭配能產生很多變化,上述只涉及到幾個較常用的幾個函數。后續大家如果需要實現一些其他功能的,可以自行編寫,也可以與筆者多多交流,完善該模塊。

????????最后希望大家不要光看文章,也可以動手敲敲代碼,加深理解。

????????如果大家發現無法刷問卷,可能就是元素定位出現了問題,可以去看看元素定位屬于上述講的哪一類。

? ? ? ? 如有錯誤之處,請批評指正!!

總結

以上是生活随笔為你收集整理的python实现刷问卷星份数(面向对象)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。