创造太阳 发表于 2020-12-11 13:29

Python+selenium宪法小卫士活动题库及自动答题源码分享

本帖最后由 创造太阳 于 2020-12-11 13:43 编辑

该源码主要利用python+selenium来进行爬取题库和自动答题。
主要思路和代码步骤如下:
首先打开网址:https://static.qspfw.com/xf2020/learn_practice_list.html
然后找到登录按钮,同时按下shift+ctrl+i,打开控制台,找到登录按钮的位置信息,然后复制xpath,以备用

点击 登录按钮后跳转到登录页面

同理,找到 用户名,密码和登录的xpath信息,以备用
处理弹窗

登录后找到 在线学习的xpath

之后找到待学习的课程等过程及xpath就不再赘述,方法相同,一步步寻找

爬取题库
进入答题页面,可以同理找到 问题的xpath和选项的xpath

选择任意一个选项,等待页面刷新,正确选项会变成绿色,且class变成‘item success’,
刚才选择的错误选项的class变成‘item error‘,
因此可以根据class的变化获得正确答案
【尝试获取class='item success'但失败了,还未寻找到解决办法,故采用另一种方法】
选择A后,采集选项的class值,如果是‘item error’的话就跳过,选择B,当不是‘item error’时就是正确答案。
【耗费时间比直接获取class=‘item success’多3倍】
然后选择下一题依次答题的xpath,答题结束后选择 学习下一主题的xpath进行跳转
将采集到的题目和正确选项答案保存到文件中,题库爬取完成

将题库导入到程序中,然后进入答题页面
题库格式为【题目/A/选项】
获得题目的xpath位置,找到其文本信息,将该文本和题库列表进行搜索
当题库中有该题目时,确定其索引位置,正确答案的索引值为其值+1,获得正确答案
然后进行判断,根据正确答案,选择要选择选项的xpath,然后进行选择,
完成该题目后选择下一题,
全部完成后提交。
关闭提交后的弹窗。

源码如下:

import time    #导入时间库
from selenium import webdriver






""" 账号密码 """
name = "账号"
password = "密码"

"""网址"""
url = "https://static.qspfw.com/xf2020/learn_practice_list.html"

chromedriver = 'chromedriver.exe'   #浏览器内核位置
chome_options = webdriver.ChromeOptions()
wd = webdriver.Chrome(chromedriver, chrome_options=chome_options)   #浏览器
wd.delete_all_cookies()# 删除cookies
wd.maximize_window()# 将浏览器最大化
wd.implicitly_wait(10)   #网页无响应或找不到标签等,最长尝试10秒
wd.get(url)
element = wd.find_element_by_xpath('//*[@id="login"]')   #登录按键
element.click()
element = wd.find_element_by_xpath('//*[@id="username"]')   #用户名
element.send_keys(name)
element = wd.find_element_by_xpath('//*[@id="password"]')    #密码
element.send_keys(password)
time.sleep(3)   #延迟3秒
element = wd.find_element_by_xpath('/html/body/div/div/form/a')   #登录
element.click()#点击
time.sleep(2)   #延迟2秒



#有时候会出现弹窗,显示 服务器忙或登录成功等弹窗,需要关闭
"""关闭浏览器弹窗"""
try:
    a = wd.switch_to.alert   #切换alert
    print(a.text)                  # 获取弹窗上的文本
    a.accept()                     # 确认,相当于点击[确定]按钮
    # a.dismiss()                      # 取消,相当于点击[取消]按钮
except:
    pass


#有时页面会出现“服务器错误”弹窗,关闭后再次登录才行,如果不需就注释掉
# """再次登录"""
# try:
#   element = wd.find_element_by_xpath('/html/body/div/div/form/a')
#   element.click()
# except:
#   pass
#
#用户未认证状态下会出现认证弹窗,如果不需就注释掉
# """关闭认证弹窗"""
# try:
#   element = wd.find_element_by_xpath('/html/body/div/div/table/tbody/tr/td/button')
#   element.click()
# except:
#   pass



"""跳转 在线学习"""

element = wd.find_element_by_xpath('/html/body/section/div/div/div/div/div/div/img')
element.click()
print("在线学习")
time.sleep(5)

'''    以下代码用于获取题库及答案
"""跳转 课程-练习   获得所有题库"""


for b in range(3,8):
    course_xpath = '//*[@id="columnList"]/div[' + str(b) + ']/div/div/div'
    practice_xpath = '//*[@id="columnList"]/div[' + str(b) + ']/div/div/div/div'
    element = wd.find_element_by_xpath(course_xpath)
    course = element.text
    print(f"打开课程 {course}")
    practice = wd.find_element_by_xpath(practice_xpath)
    practice.click()

    """获得该课程题库"""
    for num in range(1,31): #练习题目是30题,因此依次答题
      question = wd.find_element_by_xpath('//*[@id="exam_question"]').text    #获得题目
      print(question)   #打印

      for i in range(1,5): # 4个选项
            choose_xpath = '//*[@id="exam_answer"]/div[' + str(i) + ']/span'   #选项的xpath
            choose = wd.find_element_by_xpath(choose_xpath)#选择第i个

            choose.click()    #点击选项
            time.sleep(3)   #延时3秒
            all_answer_xpath = '//*[@id="exam_answer"]/div[' + str(i) + ']'   #选项选择后的xpath
            all_answer = wd.find_element_by_xpath(all_answer_xpath)
            answer_class_name = all_answer.get_attribute('class')   #获得class
            print(answer_class_name)#查看
            if answer_class_name == "itemerror" or answer_class_name == "item error":   #如果是错误就
                pass    #跳过

            #不知道为什么直接定位by_class_name(“item success”)无法找到,只好有这样的办法来通过判断class的值来确定答案
            #用by_class_name(“item success”)直接定位效率更高
            elif answer_class_name == "item success" or answer_class_name =="itemsuccess":#如果是正确
                answers = ['A','B','C','D']# A,B,C,D
                answer = answers   #在列表中的顺序
                answer_text = choose.text
                print(answer)#打印
                print(answer_text)
            try:#尝试
                #当class=="itemerror"时没有answer,故需要用try

                with open("宪法题库.txt","a") as f:
                  f.write(question + "/" + answer +"/" + answer_text + "/")   #写入题目和答案
            except:
                pass #跳过
      if num < 30:
            next = wd.find_element_by_id('next_question')#下一题
            next.click()   #点击
            time.sleep(0.1)
      else:
            pass

    back_learn_list = wd.find_element_by_xpath('/html/body/section/div/div/div/span')#返回主题列表xpath
    back_learn_list.click()   #点击
    time.sleep(3)#延迟3秒

'''



"""导入题库"""
file = "宪法题库_全.txt"    #题库文件路径
questions = open(file,"r").read()   #文本格式打开
print(questions)
question_list = questions.split('/')    #用split()函数根据 / 进行切片,生成题库列表


"""跳转 综合测评"""
element = wd.find_element_by_xpath('//*[@id="toEvaluation"]')
element.click()
print("进入综合测评,即将开始答题……")

"""跳转 开始答题页面"""
element = wd.find_element_by_xpath('/html/body/section/div/div/div/div/div/span')#开始答题
print(element.text)
element.click()   #点击




for i in range(1,11):   #一共10道题目,循环10次
    element = wd.find_element_by_xpath('//*[@id="exam_question"]')    #找到题目信息的xpath
    print(element.text)#打印查看
    question = element.text   #吧问题文本赋值给question
    question = question.strip()   #删除两端空字符
    if question in question_list:    #如果题目再题库列表中
      print(question_list.index(question))    #打印所在索引编号
      answer = question_list    #答案的索引编号是问题索引编号+1
      print(answer)   #打印答案
      if answer == "A":   #如果是A
            answer_xpath = '//*[@id="exam_answer"]/div/span'   #A项的xapth
      elif answer == "B":#如果是B
            answer_xpath = '//*[@id="exam_answer"]/div/span'   #B项的xpath
      elif answer == "C":
            answer_xpath = '//*[@id="exam_answer"]/div/span'
      elif answer == "D":
            answer_xpath = '//*[@id="exam_answer"]/div/span'
      
      time.sleep(3)   #延时3秒,模拟人工操作选择
      answer_element = wd.find_element_by_xpath(answer_xpath)   #找到证选项的xpath
      answer_element.click()   #点击
      
      next_xpath = '/html/body/section/div/div/div/div/div/div/div'#下一题的xpath
      next_element = wd.find_element_by_xpath(next_xpath)#找到下一题
      next_element.click()   #点击


submit_element = wd.find_element_by_id("submit")   #提交按钮
submit_element.click()   #点击提交


"""关闭浏览器交卷成功弹窗"""
try:
    a = wd.switch_to.alert   #切换alert
    print(a.text)                  # 获取弹窗上的文本
    a.accept()                     # 确认,相当于点击[确定]按钮
    # a.dismiss()                      # 取消,相当于点击[取消]按钮
except:
    pass


题库:
链接:https://pan.baidu.com/s/1tKPO0oK0z2bb7ldIos6-Hw
提取码:bltb
复制这段内容后打开百度网盘手机App,操作更方便哦

创造太阳 发表于 2020-12-11 15:22

bamyoo 发表于 2020-12-11 14:56
是不是题库不全,不自动答题啊。

给的测试账号好像是三年级的,其他年级的就把爬取题库那块代码取消注释爬一下就可以了。

创造太阳 发表于 2021-1-26 15:19

kai3322 发表于 2021-1-26 11:00
创造太阳 发表于 2021-1-25 18:55
取消python中的弹窗相关代码的注释,不是注释对方网站的
用哪个库?


import time    #导入时间库
from selenium import webdriver

52soft 发表于 2020-12-11 13:41

学习了,看看怎样?

红尘客栈。 发表于 2020-12-11 13:46

来晚了一步,手动答的{:301_999:}

XuYiXin 发表于 2020-12-11 13:47

{:1_918:} 抓请求接口,直接读返回值选择多好啊!!

freedown 发表于 2020-12-11 13:55

不错,这个可以有。

dzxiang 发表于 2020-12-11 13:56

太需要这个了,操作起来试试看

时光稀释 发表于 2020-12-11 14:00

感觉是不是有点过分了。每个视频后面有30题课后习题,给个3、5题意思意思不就行了。

上次手动答了300多题。谢谢分享!下次试试

872269113 发表于 2020-12-11 14:01

求成品啊

bamyoo 发表于 2020-12-11 14:15

来晚了啊,已经手动打完了。

sharokku4869 发表于 2020-12-11 14:17

厉害了,学些了,感谢大佬
页: [1] 2 3 4 5 6
查看完整版本: Python+selenium宪法小卫士活动题库及自动答题源码分享