小结受同学邀请,演示如何使用PyQt5嵌入式浏览器浏览网页,注入Javascript脚本实现自动运行。sg原帖地址:如何在Python中使用runJavaScript模拟鼠标移动页面的一个元素https://segmentfault.com/q/10...下面测试的是一个廉价机票预订网站(http://segmentfault.com/q/10)/www.flyscoot.com/),重点如下1.使用QWebEngineView加载网页并显示进度。2、在默认配置(QWebEngineProfile)中嵌入Javascript内容,这样脚本就会在所有打开的网页中执行,无论跳转到哪个URL。3、Javascript脚本根据URL中的路径名来判断当前网页的位置,从而决定执行哪个操作。Python代码示例#!/usr/bin/envpython3#-*-coding:utf-8-*-'''使用PyQt5嵌入式浏览器浏览网页,注入Javascript脚本实现自动运行。'''导入osimportsysfromdatetimeimportdatetimefromPyQt5.QtWidgets,QWebEngineProfile,QWebEngineScript,QWebEnginePageclassBrowser(QWidget):def__init__(self):super().__init__()self.init_ui()#脚本self.profile=QWebEngineProfile.defaultProfile()self.script=QWebEngineScript()self.prepare_script()definit_ui(self):self.webView=QWebEngineView()self.logEdit=QTextEdit()self.logEdit.setFixedHeight(100)self.addrEdit=QLineEdit()self.addrEdit.returnPressed.connect(self.load_url)自我.webView.urlChanged.connect(lambdai:self.addrEdit.setText(i.toDisplayString()))self.jsEdit=QLineEdit()self.jsEdit.setText('inject.js')loadUrlBtn=QPushButton('load')loadUrlBtn.clicked.connect(self.load_url)chooseJsBtn=QPushButton('选择脚本文件')chooseJsBtn.clicked.connect(self.choose_js_file)#导航/工具top=QWidget()top.setFixedHeight(80)topBox=QVBoxLayout(top)topBox.setSpacing(0)topBox.setContentsMargins(5,0,0,5)progBar=QProgressBar()progBox=QHBoxLayout()progBox.addWidget(progBar)topBox.addLayout(progBox)naviBox=QHBoxLayout()naviBox.addWidget(QLabel('URL'))naviBox.addWidget(self.addrEdit)naviBox.addWidget(loadUrlBtn)topBox.addLayout(naviBox)naviBox=QHBoxLayout()naviBox.addWidget(QLabel('注入脚本文件'))naviBox.addWidget(self.jsEdit)naviBox.addWidget(chooseJsBtn)topBox.addLayout(naviBox)self.webView.loadProgress.connect(progBar.setValue)#主界面layout=QVBoxLayout(self)layout.addWidget(self.webView)layout.addWidget(top)layout.addWidget(self.logEdit)self.show()self.resize(1024,900)self.center()def中心(自我):qr=self.frameGeometry()cp=QDesktopWidget().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())@pyqtSlot()defload_url(self):url=self.addrEdit.text().strip()如果不是url.lower().startswith('http://')\而不是url.lower().startswith('https://'):url='http://{}'.format(url)self.load(url)@pyqtSlot()defchoose_js_file(self):f,_=QFileDialog.getOpenFileName(filter="Javascript文件(*.js)")如果os.path.isfile(f):self.jsEdit.setText(f)self.prepare_script()defprepare_script(self):path=self.jsEdit.text().strip()如果不是os.path.isfile(path):self.log('invalidjspath')returnself.profile.scripts().remove(self.script)withopen(path,'r')asf:self.script.setSourceCode(f.read())self.profile.scripts().insert(self.script)self.log('注入js就绪')deflog(self,msg,*args,**kwargs):m=msg.format(*args,**kwargs)self.logEdit.append('{}{}'.format(datetime.now().strftime('%H:%M:%S'),m))defload(self,url):self.log(f'loading{url}')self.addrEdit.setText(url)self.webView.load(QUrl(url))if__name__=='__main__':app=QApplication(sys.argv)b=Browser()b.load('http://www.flyscoot.com/')sys.exit(app.exec_())Javascript脚本示例//为简单起见,这里只演示部分页面,脚本内容摘自恒、原帖functionhandle(path){//首页if(path=='/zh'){document.getElementsByClassName('radio-inline')[1].click();document.getElementById('oneway_from').value='广州(CAN)';document.getElementById('oneway_to').value='新加坡(SIN)';document.getElementById('oneway_departuredate').value='2018年9月10日';document.getElementsByClassName('btn--booking')[1].click();返回;}//选择航班if(path=='/Book/Flight'){document.getElementsByClassName('price--sale')[0].click();document.getElementsByClassName('heading-4')[0].click();document.getElementsByClassName('btn-submit')[0].click();返回;}//乘客信息if(path=='/BookFlight/Passengers'){document.getElementsByClassName('fname1')[0].value="朋名";}}lethost=document.location.hostname;if(host.endsWith('.flyscoot.com')){handle(document.location.pathname);}
