相信python大家一定很熟悉,但是通过python+selenium来实现自动化测试不知道大家是否听说过,我也是最近通过一个项目中才学到的,因为这个项目中我就是个打杂的,然后要把网页上面的一些题库手动录入数据库中,当然这个过程是真的枯燥且无味,所以我想到python,我记得在大学的时候学过这门语言,所以再次学习也就相当于是复习了,然后又进一步了解到了python+selenium可以实现自动化测试,于是乎,我开始研究怎么样将数据直接写进数据库。
通过百度了很多,在csdn上面也找了很多,最终,终于找到了一个启发我成功的实现这个功能的文章(链接:https://blog.csdn.net/weixin_44239541/article/details/89766158?utm_source=app&app_version=4.12.0&code=app_1562916241&uLinkId=usr1mkqgl919blen)
链接里面的文章中那位博主写的很详细,但是我还是想要根据我自己的理解来进行总结一下。
第一步:先在mysql中建一个表,如下图:
第二步:然后需要用python连接数据库,需要用到pymsql模块,此模块为python的三方模块,需要进行引入下载,然后创建连接的语句如下程序所示,但是我们也可以直接将其封装为一个类。
创建python文件,命名为dataManage,创建类DataManager,如下图:
代码如下:
# mysql数据库服务器,端口:3306,而且服务器是处于启动状态
# 安装pymysql:pip install pymysql
import pymysql
import threading
from settings import MYSQL_HOST, MYSQL_DB, MYSQL_PWD, MYSQL_USER
class DataManager():
# 单例模式,确保每次实例化都调用一个对象。
_instance_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not hasattr(DataManager, "_instance"):
with DataManager._instance_lock:
DataManager._instance = object.__new__(cls)
return DataManager._instance
return DataManager._instance
def __init__(self):
# 建立连接
self.conn = pymysql.connect(host=MYSQL_HOST, user=MYSQL_USER, password=MYSQL_PWD, database=MYSQL_DB, charset='utf8')
# 建立游标
self.cursor = self.conn.cursor()
def save_data(self, data):
# 数据库操作
# (1)定义一个格式化的sql语句
sql = "insert into question(`type`,`title`,`option`,`answer`) values(%s,%s,%s,%s)"
# (2)准备数据
# data = ('nancy','30','100','太好笑了')
# (3)操作
try:
self.cursor.execute(sql, data)
self.conn.commit()
except Exception as e:
print('插入数据失败', e)
self.conn.rollback() # 回滚
def __del__(self):
# 关闭游标
self.cursor.close()
# 关闭连接
self.conn.close()
第三步:创建settings.py文件用来写入连接mysql数据的各项参数,连接的ip,端口,mysql数据库密码,连接的数据库名字
如下图:
代码如下:
# 该文件存储项目中的所有配置参数
MYSQL_HOST = '127.0.0.1'
MYSQL_USER = 'root'
MYSQL_PWD = '123456' #密码
MYSQL_DB = 'test' #这个是数据库的名称
第四步:创建test.py,编写主要代码,实现获取网页上面的题库,代码如下:
from python爬题库.dataManager import DataManager
import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver import ActionChains
# 实例化数据库类对象
db = DataManager()
def to_string(s):
string = s.strip().split("\t")
string_list = []
for i in range(len(string)):
if string[i] != "":
string_list.append(string[i].strip())
return string_list
def have_alert(driver):
try:
alert = driver.switch_to.alert
return alert
except NoAlertPresentException:
return False
def get(type_work):
"""
获取试题
:param type_work: 工种名称
:return: [[题型, 题干, 选项, 答案], [], ...]
"""
# 设置最大等待时长为 10秒
driver = webdriver.Chrome() # 测试
driver.implicitly_wait(10)
driver.get("http://www.tf110.cn") # 进入界面
# http://www.tf110.cn/tf/computer/sjlogin_index.do
driver.maximize_window() # 最大化窗口
# 用户名
user_name = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[2]/form/input[2]')
user_name.send_keys("19914724023")
# 密码
user_passwd = driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[2]/form/input[3]')
user_passwd.send_keys("1234567890")
print("等待10秒,请尽快输入验证码")
time.sleep(10)
# 代替回车
# driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div/div[1]/div[2]/form/input[4]').click() # 登录
# /html/body/div[1]/div[1]/div/div[2]/div[2]/ul/li[2]/a/span[1] G1工业锅炉司炉
mouse = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[2]/div[2]/div[2]')
ActionChains(driver).move_to_element(mouse).perform()
# 点击更换工种类型
# print(driver.find_elements_by_xpath("//*[contains(text(), "+type_work+")]"))
# //span[contains(text(), '低压电工作业')]
driver.find_elements_by_xpath("//span[contains(text(), '" + type_work + "')]")[0].click()
if have_alert(driver):
driver.switch_to.alert.accept()
# 全真题库
driver.find_element_by_xpath('/html/body/div[2]/div[2]/div[1]/ul/li[2]/a').click()
# 点击弹出警告
if have_alert(driver):
driver.switch_to.alert.accept()
# 获取题目数量
cnt = driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[1]/div[2]/h1/span[2]').text
print("题目数量有" + cnt)
# 现在的题号
cnt_c = int(driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[1]/div[2]/h1/span[1]').text)
time.sleep(2)
for i in range(cnt_c, int(cnt)):
print('第' + str(i) + "/" + str(cnt) + '题', end=": ")
time.sleep(0.5)
soup = BeautifulSoup(driver.page_source, 'lxml')
# 判断试题类型
ques_type = driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[1]/div[1]').text.split(" ")[0]
print("试题类型", ques_type)
# 填入题型
if ques_type == "判断题":
ques_type = 0
elif ques_type == "单选题":
ques_type = 1
elif ques_type == "多选题":
ques_type = 2
# 获取题干
ques_text = driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[1]/div[2]/h1/span[3]').text
print("题干", ques_text)
# 选项
op_list = soup.find('div', class_='text_list').find_all('li')
op_len = len(op_list)
print("选项长度", op_len)
# 获取所有选项
op_s = ''
for lens in range(op_len):
op = to_string(op_list[lens].text)
print(op)
op_s += chr(ord('A') + lens) + op[1]
op_s += ''
print(op_s)
# 获取答案
if ques_type == 0:
time.sleep(0.4)
driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[1]/div[2]/div/ul/li[1]/a/span').click()
# driver.find_element_by_xpath('').click()
ans_s = driver.find_element_by_xpath('/html/body/div[4]/div/div/form/div/div[2]/div[1]/div[1]/a').text
ans_s = ans_s.split("参考答案")[1].strip()
if ans_s[-1] == '对':
ans_s = 'A'
elif ans_s[-1] == '错':
ans_s = 'B'
print('答案:', ans_s)
elif ques_type == 1:
for lens in range(1, op_len + 1):
driver.find_element_by_xpath(
'/html/body/div[4]/div/div/form/div/div[1]/div[2]/div/ul/li[' + str(lens) + ']/a/span').click()
ans_s = \
driver.find_element_by_xpath(
'/html/body/div[4]/div/div/form/div/div[2]/div[1]/div[1]/a').text.strip().split(" ")[-1].strip()
print(ans_s)
elif ques_type == 2:
for lens in range(1, op_len + 1):
driver.find_element_by_xpath(
'/html/body/div[4]/div/div/form/div/div[1]/div[2]/div[1]/ul/li[' + str(lens) + ']/label/a').click()
driver.find_element_by_xpath(
'/html/body/div[4]/div/div/form/div/div[1]/div[2]/div[2]/a').click()
ans_s = \
driver.find_element_by_xpath(
'/html/body/div[4]/div/div/form/div/div[2]/div[1]/div[1]/a').text.strip().split(" ")[-1].strip()
print(ans_s)
# 下一题
driver.find_element_by_xpath('/html/body/div[4]/div/div/div/div[1]/ul/li[3]').click()
data = (ques_type, ques_text, op_s, ans_s)
db.save_data(data)
if __name__ == '__main__':
get("A特种设备相关管理(限电梯安全管理)")
这样,就能实现直接写入题库了
最后还要说一下,这个是在谷歌浏览器上进行的,所以还需要下载一个驱动器,这个是要与你使用的谷歌版本相对应的,记住还要添加环境变量,链接如下: