使用PyQt5和硒时,窗口标题显示为“无响应”。 脚本执行完成后,将显示进度条和控制台发射流。需要帮助以解决此问题。
from selenium import webdriver
from selenium.common.exceptions import
TimeoutException,NoSuchElementException,ElementClickInterceptedException
from selenium.webdriver.support.ui import WebDriverWait,Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.common.action_chains import ActionChains
import time
import os.path
import pandas as pd
import csv
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
class EmittingStream(QtCore.QObject):
textWritten = QtCore.pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
class Ui_Fuse(object):
def launch_Selenium_Thread(self):
_translate = QtCore.QCoreApplication.translate
self.pushButton.setEnabled(False)
self.progressBar.setValue(0)
self.textEdit.clear()
t = threading.Thread(target=self.generate())
t.start()
def loaddata(self):
self.completed = 0
while self.completed < 100:
self.completed += 0.0001
self.progressBar.setValue(self.completed)
def setupUi(self, Fuse):
Fuse.setObjectName("Fuse")
Fuse.resize(513, 284)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
Fuse.setFont(font)
self.label = QtWidgets.QLabel(Fuse)
self.label.setGeometry(QtCore.QRect(90, 67, 71, 20))
self.label.setObjectName("label")
self.LineEdit = QtWidgets.QLineEdit(Fuse)
self.LineEdit.setGeometry(QtCore.QRect(170, 60, 181, 31))
self.LineEdit.setObjectName("textEdit")
self.LineEdit_2 = QtWidgets.QLineEdit(Fuse)
self.LineEdit_2.setGeometry(QtCore.QRect(170, 100, 181, 31))
self.LineEdit_2.setObjectName("textEdit_2")
self.LineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
self.pushButton = QtWidgets.QPushButton(Fuse)
self.pushButton.setGeometry(QtCore.QRect(169, 150, 90, 31))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.launch_Selenium_Thread)
self.pushButton.clicked.connect(self.loaddata)
self.pushButton_2 = QtWidgets.QPushButton(Fuse)
self.pushButton_2.setGeometry(QtCore.QRect(262, 150, 90, 31))
self.pushButton_2.setObjectName("pushButton_3")
self.pushButton_2.clicked.connect(self.clearall)
self.label_2 = QtWidgets.QLabel(Fuse)
self.label_2.setGeometry(QtCore.QRect(89, 107, 71, 20))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Fuse)
self.label_3.setGeometry(QtCore.QRect(180, 127, 181, 30))
self.label_3.setObjectName("label_3")
self.progressBar = QtWidgets.QProgressBar(Fuse)
self.progressBar.setEnabled(True)
self.progressBar.setGeometry(QtCore.QRect(8, 270, 506, 10))
self.progressBar.setLayoutDirection(QtCore.Qt.LeftToRight)
self.progressBar.setAutoFillBackground(False)
self.progressBar.setProperty("value", 24)
self.progressBar.setAlignment(QtCore.Qt.AlignJustify)
self.progressBar.setInvertedAppearance(False)
self.progressBar.setObjectName("progressBar")
self.textEdit = QtWidgets.QTextEdit(Fuse)
self.textEdit.setGeometry(QtCore.QRect(8, 200, 497, 60))
self.textEdit.setObjectName("textEdit")
self.textEdit.setFont(font)
self.textEdit.setReadOnly(True)
self.retranslateUi(Fuse)
QtCore.QMetaObject.connectSlotsByName(Fuse)
def retranslateUi(self, Fuse):
_translate = QtCore.QCoreApplication.translate
Fuse.setWindowTitle(_translate("Fuse", "Fuse | Invoice Generation"))
self.label.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-size:10pt; font-weight:600;\">User Name</span></p></body></html>"))
self.pushButton.setText(_translate("Fuse", "Submit"))
self.pushButton_2.setText(_translate("Fuse", "Reset"))
self.label_2.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-size:10pt; font-weight:600;\">Password</span></p></body></html>"))
self.label_3.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-size:7pt; color:red; font-weight:600;\">Invalid User Name or Password</span></p></body></html>"))
self.label_3.hide()
Fuse.setWindowFlags( QtCore.Qt.CustomizeWindowHint | QtCore.Qt.MSWindowsFixedSizeDialogHint |QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint )
def clearall(self):
self.LineEdit.clear()
self.LineEdit_2.clear()
self.label_3.clear()
self.textEdit.clear()
self.LineEdit.setEnabled(True)
self.LineEdit_2.setEnabled(True)
self.pushButton.setEnabled(True)
def __init__(self, parent=None, **kwargs):
sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
sys.stderr = EmittingStream(textWritten=self.normalOutputWritten)
def __del__(self):
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
def normalOutputWritten(self, text):
cursor = self.textEdit.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
self.textEdit.setTextCursor(cursor)
self.textEdit.ensureCursorVisible()
def generate(self):
self.LineEdit.setEnabled(False)
self.LineEdit_2.setEnabled(False)
self.pushButton.setEnabled(False)
self.textEdit.clear()
options = Options()
options.add_argument("--headless")
profile = FirefoxProfile()
driver = webdriver.Firefox(firefox_profile=profile,firefox_options=options,executable_path= os.path.expandvars('%userprofile%\\Desktop\\RPA\\Tools\\geckodriver.exe'))
driver.get("https://example.com/Login.aspx")
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "loginBtnn")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
search_field = driver.find_element_by_id("txtUserName")
search_field.clear()
username = self.LineEdit.text()
search_field.send_keys(username)
search_field = driver.find_element_by_id("txtPassword")
search_field.clear()
password = self.LineEdit_2.text()
search_field.send_keys(password)
time.sleep(5)
driver.find_element_by_id("BtnLogin").click()
self.textEdit.insertPlainText('Clicked on Login')
time.sleep(5)
try:
element = driver.find_element_by_xpath("//span[contains(@id,'lblFailure')]")
if element.text == "Invalid User Name or Password":
self.textEdit.insertPlainText("Invalid User Name or Password")
self.label_3.show()
self.LineEdit.setEnabled(True)
self.LineEdit_2.setEnabled(True)
self.pushButton.setEnabled(True)
driver.quit()
driver.close()
except NoSuchElementException:
self.textEdit.insertPlainText("Correct User Name or Password")
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.XPATH, "/html/body/form/div[4]/a/img")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
driver.find_element_by_xpath("/html/body/form/div[4]/a/img").click()
self.textEdit.insertPlainText('Clicked Product Links')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "lnkFuse")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
driver.find_element_by_id("lnkFuse").click()
self.textEdit.insertPlainText('Clicked on Fuse Link')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.XPATH, "//span[@class='Invoice Processing'][contains(.,'Invoice Processing')]")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
element_to_hover_over = driver.find_element_by_xpath("//span[@class='Invoice Processing'][contains(.,'Invoice Processing')]")
hover = ActionChains(driver).move_to_element(element_to_hover_over)
hover.perform()
self.textEdit.insertPlainText('Clicked on Invoice Processing')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.XPATH, "//a[@href='../../RS/Batch/AuditInvoice.aspx']")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
driver.find_element_by_xpath("//a[@href='../../RS/Batch/AuditInvoice.aspx']").click()
self.textEdit.insertPlainText('Clicked on Audit Invoices')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "MainContent_ddlSearchInvoiceStatus")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
invoice_audit = 'Audited'
InvoiceStatus = Select(driver.find_element_by_id("MainContent_ddlSearchInvoiceStatus"))
for option in InvoiceStatus.options:
option_text = option.text
if invoice_audit in option_text:
option.click()
break
self.textEdit.insertPlainText('Selected Audited from Dropdown')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "MainContent_btnSearch")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
driver.find_element_by_id('MainContent_btnSearch').click()
self.textEdit.insertPlainText('Clicked on Search Button')
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "MainContent_ddlItemsPerPage")));
except TimeoutException:
self.textEdit.insertPlainText('Timed out waiting for page to load')
element = driver.find_element_by_id('MainContent_ddlItemsPerPage')
element.location_once_scrolled_into_view
driver.find_element_by_id('MainContent_ddlItemsPerPage').click()
items_perpage = '500'
records_list = Select(driver.find_element_by_id("MainContent_ddlItemsPerPage"))
for option in records_list.options:
option_text = option.text
if items_perpage in option_text:
option.click()
break
time.sleep(5)
self.textEdit.insertPlainText('Selected Max items per page')
list_links = driver.find_elements_by_partial_link_text('Generate')
time.sleep(5)
id_list = []
for i in list_links:
data = i.get_attribute('id')
self.textEdit.insertPlainText(data)
id_list.append(data)
id_df = pd.DataFrame(id_list)
self.textEdit.insertPlainText(id_df)
for row in id_df.values:
row_val = str(row)[2:-2]
try:
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, "MainContent_gvAuditInvoice")));
self.textEdit.insertPlainText('Element Found')
element = driver.find_element_by_id(row_val)
element.location_once_scrolled_into_view
WebDriverWait(driver, 60000).until(
EC.element_to_be_clickable((By.ID, row_val)));
driver.find_element_by_id(row_val).click()
localtime = time.strftime("%m-%d-%Y %I:%M:%S")
self.textEdit.insertPlainText(row_val + "|" + 'Clicked' + '|' + localtime)
time.sleep(5)
except ElementClickInterceptedException:
continue
self.textEdit.insertPlainText('Timed out waiting for page to load')
time.sleep(5)
self.textEdit.insertPlainText('Completed')
self.LineEdit.clear()
self.LineEdit_2.clear()
self.label_3.clear()
self.LineEdit.setEnabled(True)
self.LineEdit_2.setEnabled(True)
self.pushButton.setEnabled(True)
self.stop_Selenium_Thread()
def stop_Selenium_Thread(self):
_translate = QtCore.QCoreApplication.translate
self.pushButton.setEnabled(True)
t = threading.Thread(target=self.stop_Selenium_Thread)
for i, t in enumerate(self.generate()):
t.join()
print('Thread {} Stopped'.format(i))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Fuse = QtWidgets.QDialog()
ui = Ui_Fuse()
ui.setupUi(Fuse)
Fuse.show()
sys.exit(app.exec_())
我的实际结果应该是当我按下应用程序上的“提交”按钮时,程序应该开始执行脚本,并且代码中给出的self.textEdit.insertPlainText应该随着进度条移动而流进文本编辑中。
答案 0 :(得分:1)
首先,您有以下不良编程习惯:
另一方面,转到Qt,您会遇到以下错误:
另一方面,我尚未测试您的代码,但我发现您的错误之一是
t = threading.Thread(target=self.generate())
由于您要调用函数而不是将其传递给函数,因此它必须是
t = threading.Thread(target=self.generate)
考虑到上述情况,我实现了以下内容:
fuse_ui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'fuse.ui'
#
# Created by: PyQt5 UI code generator 5.12.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Fuse(object):
def setupUi(self, Fuse):
Fuse.setObjectName("Fuse")
Fuse.resize(556, 513)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(Fuse.sizePolicy().hasHeightForWidth())
Fuse.setSizePolicy(sizePolicy)
self.verticalLayout = QtWidgets.QVBoxLayout(Fuse)
self.verticalLayout.setObjectName("verticalLayout")
spacerItem = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.verticalLayout.addItem(spacerItem)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
spacerItem1 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.userNameLabel = QtWidgets.QLabel(Fuse)
self.userNameLabel.setObjectName("userNameLabel")
self.gridLayout.addWidget(self.userNameLabel, 0, 0, 1, 1)
self.userNameLineEdit = QtWidgets.QLineEdit(Fuse)
self.userNameLineEdit.setObjectName("userNameLineEdit")
self.gridLayout.addWidget(self.userNameLineEdit, 0, 1, 1, 1)
self.passwordLabel = QtWidgets.QLabel(Fuse)
self.passwordLabel.setObjectName("passwordLabel")
self.gridLayout.addWidget(self.passwordLabel, 1, 0, 1, 1)
self.passwordLineEdit = QtWidgets.QLineEdit(Fuse)
self.passwordLineEdit.setObjectName("passwordLineEdit")
self.gridLayout.addWidget(self.passwordLineEdit, 1, 1, 1, 1)
self.invalidLabel = QtWidgets.QLabel(Fuse)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.invalidLabel.sizePolicy().hasHeightForWidth())
self.invalidLabel.setSizePolicy(sizePolicy)
self.invalidLabel.setAlignment(QtCore.Qt.AlignCenter)
self.invalidLabel.setObjectName("invalidLabel")
self.gridLayout.addWidget(self.invalidLabel, 2, 1, 1, 1)
self.widget = QtWidgets.QWidget(Fuse)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.submitButton = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.submitButton.sizePolicy().hasHeightForWidth())
self.submitButton.setSizePolicy(sizePolicy)
self.submitButton.setObjectName("submitButton")
self.horizontalLayout.addWidget(self.submitButton)
self.resetButton = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.resetButton.sizePolicy().hasHeightForWidth())
self.resetButton.setSizePolicy(sizePolicy)
self.resetButton.setObjectName("resetButton")
self.horizontalLayout.addWidget(self.resetButton)
self.gridLayout.addWidget(self.widget, 3, 1, 1, 1)
self.horizontalLayout_2.addLayout(self.gridLayout)
spacerItem2 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem2)
self.verticalLayout.addLayout(self.horizontalLayout_2)
spacerItem3 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.verticalLayout.addItem(spacerItem3)
self.logTextEdit = QtWidgets.QTextEdit(Fuse)
self.logTextEdit.setObjectName("logTextEdit")
self.verticalLayout.addWidget(self.logTextEdit)
self.progressBar = QtWidgets.QProgressBar(Fuse)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.verticalLayout.addWidget(self.progressBar)
self.retranslateUi(Fuse)
QtCore.QMetaObject.connectSlotsByName(Fuse)
def retranslateUi(self, Fuse):
_translate = QtCore.QCoreApplication.translate
Fuse.setWindowTitle(_translate("Fuse", "Dialog"))
self.userNameLabel.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-weight:600;\">User Name</span></p></body></html>"))
self.passwordLabel.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-weight:600;\">Password</span></p></body></html>"))
self.invalidLabel.setText(_translate("Fuse", "<html><head/><body><p><span style=\" font-size:7pt; color:red; font-weight:600;\">Invalid User Name or Password</span></p></body></html>"))
self.submitButton.setText(_translate("Fuse", "Submit"))
self.resetButton.setText(_translate("Fuse", "Reset"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Fuse = QtWidgets.QDialog()
ui = Ui_Fuse()
ui.setupUi(Fuse)
Fuse.show()
sys.exit(app.exec_())
fusi_worker.py
import os
import time
from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException,ElementClickInterceptedException
from selenium.webdriver.support.ui import WebDriverWait,Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.common.action_chains import ActionChains
from PyQt5 import QtCore
import pandas as pd
class FusiWorker(QtCore.QObject):
progressChanged = QtCore.pyqtSignal(int)
logSignal = QtCore.pyqtSignal(str)
invalidSignal = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
@QtCore.pyqtSlot(str, str)
def start(self, username, password):
options = Options()
options.add_argument("--headless")
profile = FirefoxProfile()
driver_path = os.path.expandvars('%userprofile%\\Desktop\\RPA\\Tools\\geckodriver.exe')
driver = webdriver.Firefox(firefox_profile=profile, options=options, executable_path=driver_path)
driver.get("https://example.com/Login.aspx")
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "loginBtnn")));
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
search_field = driver.find_element_by_id("txtUserName")
search_field.clear()
search_field.send_keys(password)
time.sleep(5)
driver.find_element_by_id("BtnLogin").click()
self.logSignal.emit('Clicked on Login')
time.sleep(5)
try:
element = driver.find_element_by_xpath("//span[contains(@id,'lblFailure')]")
if element.text == "Invalid User Name or Password":
self.logSignal.emit("Invalid User Name or Password")
self.invalidSignal.emit()
driver.quit()
driver.close()
except NoSuchElementException:
self.logSignal.emit("Correct User Name or Password")
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.XPATH, "/html/body/form/div[4]/a/img")));
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
driver.find_element_by_xpath("/html/body/form/div[4]/a/img").click()
self.logSignal('Clicked Product Links')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "lnkFuse")));
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
driver.find_element_by_id("lnkFuse").click()
self.logSignal.emit('Clicked on Fuse Link')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.XPATH, "//span[@class='Invoice Processing'][contains(.,'Invoice Processing')]")));
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
element_to_hover_over = driver.find_element_by_xpath("//span[@class='Invoice Processing'][contains(.,'Invoice Processing')]")
hover = ActionChains(driver).move_to_element(element_to_hover_over)
hover.perform()
self.logSignal.emit('Clicked on Invoice Processing')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.XPATH, "//a[@href='../../RS/Batch/AuditInvoice.aspx']")))
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
driver.find_element_by_xpath("//a[@href='../../RS/Batch/AuditInvoice.aspx']").click()
self.logSignal.emit('Clicked on Audit Invoices')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "MainContent_ddlSearchInvoiceStatus")))
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
invoice_audit = 'Audited'
InvoiceStatus = Select(driver.find_element_by_id("MainContent_ddlSearchInvoiceStatus"))
for option in InvoiceStatus.options:
option_text = option.text
if invoice_audit in option_text:
option.click()
break
self.logSignal.emit('Selected Audited from Dropdown')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "MainContent_btnSearch")))
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
driver.find_element_by_id('MainContent_btnSearch').click()
self.logSignal.emit('Clicked on Search Button')
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "MainContent_ddlItemsPerPage")))
except TimeoutException:
self.logSignal.emit('Timed out waiting for page to load')
element = driver.find_element_by_id('MainContent_ddlItemsPerPage')
element.location_once_scrolled_into_view
driver.find_element_by_id('MainContent_ddlItemsPerPage').click()
items_perpage = '500'
records_list = Select(driver.find_element_by_id("MainContent_ddlItemsPerPage"))
for option in records_list.options:
option_text = option.text
if items_perpage in option_text:
option.click()
break
time.sleep(5)
self.logSignal.emit('Selected Max items per page')
list_links = driver.find_elements_by_partial_link_text('Generate')
time.sleep(5)
id_list = []
for i in list_links:
data = i.get_attribute('id')
self.logSignal.emit(data)
id_list.append(data)
# TODO
id_df = pd.DataFrame(id_list)
self.logSignal.emit(id_df.to_string())
for row in id_df.values:
row_val = str(row)[2:-2]
try:
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, "MainContent_gvAuditInvoice")))
self.logSignal.emit('Element Found')
element = driver.find_element_by_id(row_val)
element.location_once_scrolled_into_view
WebDriverWait(driver, 60000).until(EC.element_to_be_clickable((By.ID, row_val)))
driver.find_element_by_id(row_val).click()
localtime = time.strftime("%m-%d-%Y %I:%M:%S")
self.logSignal.emit(row_val + "|" + 'Clicked' + '|' + localtime)
time.sleep(5)
except ElementClickInterceptedException:
continue
self.logSignal.emit('Timed out waiting for page to load')
time.sleep(5)
self.logSignal.emit('Completed')
self.finished.emit()
@QtCore.pyqtSlot()
def load_data(self):
completed = 0
while completed < 100:
completed += 0.0001
self.progressChanged.emit(completed)
time.sleep(0.01)
main.py
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
from fuse_worker import FusiWorker
from fuse_ui import Ui_Fuse
class Fuse(QtWidgets.QDialog, Ui_Fuse):
def __init__(self, parent=None):
super(Fuse, self).__init__(parent)
self.setupUi(self)
self.setWindowFlags(QtCore.Qt.CustomizeWindowHint |
QtCore.Qt.MSWindowsFixedSizeDialogHint |
QtCore.Qt.WindowCloseButtonHint |
QtCore.Qt.WindowMinimizeButtonHint)
self.init()
self.connections()
def init(self):
self._worker = FusiWorker()
self.reset()
thread = QtCore.QThread(self)
thread.start()
self._worker.moveToThread(thread)
self.progressBar.setValue(0)
def connections(self):
self.submitButton.clicked.connect(self.submit)
self.resetButton.clicked.connect(self.reset)
self._worker.logSignal.connect(self.logTextEdit.insertPlainText)
self._worker.invalidSignal.connect(self.invalidate)
self._worker.finished.connect(self.reset)
self._worker.progressChanged.connect(self.progressBar.setValue)
self.progressBar.setValue(0)
@QtCore.pyqtSlot()
def submit(self):
username = self.userNameLineEdit.text()
password = self.passwordLineEdit.text()
self.logTextEdit.clear()
self.userNameLineEdit.setEnabled(False)
self.passwordLineEdit.setEnabled(False)
threading.Thread(target=self._worker.start, args=(username, password,), daemon=True).start()
threading.Thread(target=self._worker.load_data, daemon=True).start()
@QtCore.pyqtSlot()
def reset(self):
self.userNameLineEdit.clear()
self.passwordLineEdit.clear()
self.invalidLabel.hide()
self.userNameLineEdit.setEnabled(True)
self.passwordLineEdit.setEnabled(True)
self.submitButton.setEnabled(True)
@QtCore.pyqtSlot()
def invalidate(self):
self.invalidLabel.show()
self.reset()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Fuse()
w.show()
sys.exit(app.exec_())
这些文件必须位于同一文件夹中
├── fuse_ui.py
├── fuse_worker.py
└── main.py