[自用基础]selenium网页自动化-调试心得

图书馆座位总是抢不到,打算写一个python脚本实现自动化

初步构想:

1.0

实现基本功能:座位捡漏,输出座位信息,记住密码,保存签到二维码

实现基本ui: 输入密码,输入学号,选择校区,信息输出提示,浏览器内核选择

2.0

新加功能:明日预约,做一道复杂题目实现->超时前自动退座

新加ui: 优化ui卡顿,明日预约选择按钮,超时前自动退座选项,置顶/提示音

3.0

手机端,自动悬浮,自动提示音

...

目录

1.0阶段调试心得---非ui:

定位元素:

获取元素属性

延时

异常捕捉机制

下载图片,以日期命名

1.0阶段调试心得---ui:

textBrowser输出信息

pyqt三个工具的使用

界面和逻辑分离

设置信号

设置图标

设置背景

实时输出信息到textBrowser

获取lineEdit输入

样式表-设置控件的透明度

1.0阶段调试心得---体会:


1.0阶段调试心得---非ui:

定位元素:

  • 找到元素不代表元素就可以点击(猜测没有彻底加载完),所以在点击前,最好先确认可以点击:is_enabled
wait.until(lambda divers: browser.find_element(By.XPATH, 'xpath路径').is_enabled())

对于有的元素则是需要先确定可以看到:

wait.until(lambda divers: browser.find_element(By.XPATH, 'xpath路径').is_displayed())
  • 其次,就算元素可以点击也可能点击不到,可能是因为selenium的click真的是模拟,页面不划动到元素所在位置就不能点击(欢迎大佬指教,应该与ajax无关,因为这个网页不含ajax)。可能有两种情况,需要根据自己的网页判断:
1.被点击元素需要页面下滑 才能出现
2.被点击元素需要页面缩小(注意不是浏览器窗口缩放) 才能出现
# 实现滑动
js_glide = "window.scrollBy(0,1200);" # (左-右+,上-下+)
browser.execute_script(js_glide)
# 有个问题,执行多次是会下滑多次吗,还是不变??

# 实现页面内部缩放
js_zoom_in = "document.body.style.zoom='0.5'" # >1放大 <1缩小
browser.execute_script(js_zoom_in)

关于这上述代码的介绍:

Window.scrollBy() - Web API 接口参考 | MDN

Selenium:网页屏幕缩放(调整分辨率)与滚动条移动_selenium缩放网页比例_丶凉的博客-CSDN博客

  • 还有一个粗心犯的错,find_elements()返回的是一个列表,所以需要列表索引来实现点击等等
  • 还有一个很容易忽略的地方,定位元素的顺序,尤其包括要点击的元素。比如说要定位页面A的元素a,b。其中a元素用来点击实现页面跳转,b用来获取文本信息。一定要先获取b后再点击a。

获取元素属性

(86条消息) WebElement接口获取值_weixin_30652879的博客-CSDN博客

  size  获取元素的尺寸
  text  获取元素的文本
  get_attribute(name)  获取属性值
  location  获取元素坐标,先找到要获取的元素,再调用该方法
  page_source  返回页面源码
  driver.title  返回页面标题
  current_url  获取当前页面的URL
  is_displayde()  判断该元素是否可见
  is_enabled()  判断元素是否被使用
  is_selected()  判断元素是否被选中
  tag_name  返回元素的tagName

text获取时候,不知道为什么之前对,后来啥也没改就不对了,换成下边这个就好啦

myroom = room_number[0].get_attribute('textContent') # room_number[0]是一个定位到的元素

延时

http://t.csdn.cn/HLynD

介绍了常用的三种延时,看完后我把所有的sleep都换成了wait.untill哈哈哈哈,果然快了不少

异常捕捉机制

有的异常出现是概率事件的必然,不是代码的问题。比如说加载一个页面,可能由于网速问题加载不出来,代码会直接终止报错,这时候异常捕捉就起到了大作用。

(86条消息) Python异常捕获与处理_python异常捕获和处理_宗而研之的博客-CSDN博客

这篇比较全面,让我怀疑我的用法很低效,还有什么更好的方法吗?

# 出现异常(找不到元素),就下滑,直到找到元素
while 1:
        try:
            optional_room[0].click()
        except:
            js = "window.scrollBy(0,1200);"
            browser.execute_script(js)
        else:
            break

下载图片,以日期命名

qrcode_url = browser.find_element(By.XPATH,'//img[@id="qrcode"]').get_attribute('src')
qrcode_data = requests.get(url=qrcode_url).content
img_path = datetime.datetime.now().strftime('%Y-%m-%d')+'签到.jpg'

1.0阶段调试心得---ui:

textBrowser输出信息

  • self.textBrowser.append(mes) 输出信息的时候,不论如何追加,都是等代码全部运行完,才更新上去(好像,不重要,先知道正确的吧)。如果不想换行,append()换成insertPlainText()可以。
    def printf(self, mes):
        self.textBrowser.append(mes)
        self.cursot = self.textBrowser.textCursor()
        self.textBrowser.moveCursor(self.cursot.End)
        QApplication.processEvents() # 加上这一行就会实时更新了

pyqt三个工具的使用

  • designer 用来设计ui,会自动生成.ui代码
  • pyuic 将上述工具生成的ui代码转换为py代码
  • pyrcc 将图片转换为.qrc资源文件后,转换为py代码。(主要是打包exe时候,不知道怎么带图片,网上推荐这样)

qrc格式如下,其中文件名需要自己手动更改。网上有自动生成的脚本下次找找

<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/image">
<file alias="background2.png">image/background2.png</file>
<file alias="background.png">image/background.png</file>
<file alias="icon2.ico">image/icon2.ico</file>
</qresource>
</RCC>

前缀: prefix

别名: alias

好像有别名的话,只能用别名,别名可以不加(待考证),相对路径,注意qrc文件的位置

使用方法:

 self.setWindowIcon(QIcon(':/icon2.ico'))

界面和逻辑分离

之前自动生成的ui,经过pyuic转换为py脚本(名字:ui.py) 后,就不要在里边添加管控其逻辑的代码啦~不然稍微一改ui功能就没有了。所以最好的方法是单独放一个文件(名字:ui_function.py)。然后主函数调用(文件名:main.m)!

其中ui_function.py涉及到的常用模块(ctrl+f可以搜索):

设置信号

设置图标

设置背景

实时输出信息到textBrowser

获取lineEdit输入

# ui.py
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ugly.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_StudyCat(object):
    def setupUi(self, StudyCat):
        StudyCat.setObjectName("StudyCat")
        StudyCat.resize(500, 500)
        StudyCat.setMinimumSize(QtCore.QSize(500, 500))
        StudyCat.setMaximumSize(QtCore.QSize(500, 500))
        self.pushButton = QtWidgets.QPushButton(StudyCat)
        self.pushButton.setGeometry(QtCore.QRect(70, 450, 93, 28))
        self.pushButton.setStyleSheet("background-color:rgba(255,255,255,200);")
        self.pushButton.setObjectName("pushButton")
        self.label_4 = QtWidgets.QLabel(StudyCat)
        self.label_4.setGeometry(QtCore.QRect(20, 10, 471, 51))
        self.label_4.setStyleSheet("font: 30pt \"Arial\";")
        self.label_4.setTextFormat(QtCore.Qt.PlainText)
        self.label_4.setObjectName("label_4")
        self.textBrowser = QtWidgets.QTextBrowser(StudyCat)
        self.textBrowser.setGeometry(QtCore.QRect(210, 100, 271, 381))
        self.textBrowser.setStyleSheet("background-color:rgba(255,255,255,100);")
        self.textBrowser.setLineWrapColumnOrWidth(0)
        self.textBrowser.setObjectName("textBrowser")
        self.label_5 = QtWidgets.QLabel(StudyCat)
        self.label_5.setGeometry(QtCore.QRect(210, 80, 72, 15))
        self.label_5.setObjectName("label_5")
        self.checkBox = QtWidgets.QCheckBox(StudyCat)
        self.checkBox.setGeometry(QtCore.QRect(70, 400, 91, 19))
        self.checkBox.setObjectName("checkBox")
        self.layoutWidget = QtWidgets.QWidget(StudyCat)
        self.layoutWidget.setGeometry(QtCore.QRect(30, 80, 171, 281))
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label = QtWidgets.QLabel(self.layoutWidget)
        self.label.setObjectName("label")
        self.verticalLayout_2.addWidget(self.label)
        self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget)
        self.lineEdit.setStyleSheet("background-color:rgba(255,255,255,100);")
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout_2.addWidget(self.lineEdit)
        self.label_2 = QtWidgets.QLabel(self.layoutWidget)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_2.addWidget(self.label_2)
        self.lineEdit_2 = QtWidgets.QLineEdit(self.layoutWidget)
        self.lineEdit_2.setStyleSheet("background-color:rgba(255,255,255,100);")
        self.lineEdit_2.setText("")
        self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.verticalLayout_2.addWidget(self.lineEdit_2)
        self.label_3 = QtWidgets.QLabel(self.layoutWidget)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_2.addWidget(self.label_3)
        self.comboBox = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox.setAutoFillBackground(False)
        self.comboBox.setStyleSheet("background-color:rgba(255,255,255,100);")
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.verticalLayout_2.addWidget(self.comboBox)

        self.retranslateUi(StudyCat)
        QtCore.QMetaObject.connectSlotsByName(StudyCat)

    def retranslateUi(self, StudyCat):
        _translate = QtCore.QCoreApplication.translate
        StudyCat.setWindowTitle(_translate("StudyCat", "StudyCat"))
        self.pushButton.setText(_translate("StudyCat", "登录"))
        self.label_4.setText(_translate("StudyCat", "好好学习,天天向上"))
        self.label_5.setText(_translate("StudyCat", "选座信息:"))
        self.checkBox.setText(_translate("StudyCat", "记住密码"))
        self.label.setText(_translate("StudyCat", "学号:"))
        self.label_2.setText(_translate("StudyCat", "密码:"))
        self.label_3.setText(_translate("StudyCat", "校区:"))
        self.comboBox.setItemText(0, _translate("StudyCat", "b"))
        self.comboBox.setItemText(1, _translate("StudyCat", "w"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    StudyCat = QtWidgets.QWidget()
    ui = Ui_StudyCat()
    ui.setupUi(StudyCat)
    StudyCat.show()
    sys.exit(app.exec_())
# ui_function.py
import ctypes
from PyQt5.QtGui import QPainter, QPixmap, QIcon
import ui
from ugly import *
from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog
import get
import time
import os
import main
from PyQt5 import QtCore, QtGui, QtWidgets
import resource_rc
# 本脚本用于实现ui的功能
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") 
# 用于解决任务栏图标和exe图标不一致:设置任务栏图标

class MainCode(QMainWindow,ui.Ui_StudyCat):      #继承自自动生成的界面类
    def __init__(self):
        QMainWindow.__init__(self)
        ugly.Ui_StudyCat.__init__(self)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.onclick)
        self.checkBox.clicked.connect(self.rem_password) # 设置信号
        self.setWindowIcon(QIcon(':/icon2.ico')) # 设置图标

    def onclick(self):
        main.login =True
        get.get_seat(self,[self.lineEdit.text(), self.lineEdit_2.text(), self.comboBox.currentText()])

    def printf(self, mes): #实时输出信息到textBrowser
        self.textBrowser.append(mes)
        self.cursot = self.textBrowser.textCursor()
        self.textBrowser.moveCursor(self.cursot.End)
        QApplication.processEvents()

    # 简陋实现记住密码:输入行为空,则写入密码到输入行,输入行有密码,则写入密码到password.txt,后期改进考虑mysql
    def rem_password(self):
        if self.checkBox.isChecked(): # 记住密码被选中
            if len(self.lineEdit_2.text())!=0: # 保存密码
                Note = open('password.txt', mode='w')
                Note.write(self.lineEdit.text() + '\n' + self.lineEdit_2.text() )#+ '\n' + self.comboBox.currentText())
                Note.close()
            else: # 输出已保存的密码
                Note = open('password.txt', mode='r')
                contents = Note.read().splitlines()
                Note.close()
                self.lineEdit.setText(contents[0])
                self.lineEdit_2.setText(contents[1])
        else: #未被选中 清空
            self.lineEdit.clear()
            self.lineEdit_2.clear()

    # 设置背景
    def paintEvent(self, event):
        painter = QPainter(self)
        pixmap = QPixmap(":/background2.png")
        # 绘制窗口背景,平铺到整个窗口,随着窗口改变而改变
        painter.drawPixmap(self.rect(), pixmap)
# main.py
import ui #导入自动生成的ui.py文件
import ui_function 
from ui_function import *
import sys

if __name__ == '__main__':
    # 只有直接运行这个脚本,才会往下执行
    # 别的脚本文件执行,不会调用这个条件句
    # 实例化,传参
    app = QApplication(sys.argv)
    # 创建对象
    mainWindow = QMainWindow()
    md = ui_function.MainCode()
    md.show()
    sys.exit(app.exec_())

样式表-设置控件的透明度

background-color:rgba(255,255,255,100);

最后一个数字越大,透明度越低

1.0阶段调试心得---体会:

写博客总结时,才发现好多东西真就cv别人,倒也没啥,只是比较基础的部分,自己也还是不懂原理,甚至函数具体参数的含义,单纯的有用就行,大概记住涉及的函数名,不理解,不吸收,某种角度讲只是增强了cv能力。而且这样调试起来很慢,不知道问题出在哪里。

如上述,导致很多东西都是拼凑起来的,没有系统的学习,可能效率很低,代码乱七八糟。。。。考完试继续学习吧~

debug不熟练,好多都是不停的print输出看结果的,倒也可以忍受,但是我的print输出的都是乱码单纯的用来标志哪一行代码有问题,,,,其实大部分代码系统的报错就足以说明问题,如果说except捕捉了所有异常,导致查不出原因,那就不该设置捕捉所有异常。不过还学到了一个很有用的东西,编辑配置,选择模拟输出控制台的终端,好多不知道为啥不报错的错就报了。

pyqt的界面可视化操作,学的不行,好多自动化的功能没用上,比如自动选择资源文件。

不过,最后还是有成就感的,耶,但还需要继续努力!!!!

待更新。。。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值