Python实现网页截图(PyQT5)过程解析
方案说明
功能要求:实现网页加载后将页面截取成长图片
涉及模块:PyQT5PIL
逻辑说明:
1:完成窗口设置,利用PyQT5QWebEngineView加载网页地址,待网页加载完成后,调用check_pag;
classMainWindow(QMainWindow): def__init__(self,parent=None): super(MainWindow,self).__init__(parent) self.setWindowTitle('易哈佛') self.temp_height=0 self.setWindowFlag(Qt.WindowMinMaxButtonsHint,False)#禁用最大化,最小化 #self.setWindowFlag(Qt.WindowStaysOnTopHint,True)#窗口顶置 self.setWindowFlag(Qt.FramelessWindowHint,True)#窗口无边框 defurlScreenShot(self,url): self.browser=QWebEngineView() self.browser.load(QUrl(url)) geometry=self.chose_screen() self.setGeometry(geometry) self.browser.loadFinished.connect(self.check_page) self.setCentralWidget(self.browser) defget_page_size(self): size=self.browser.page().contentsSize() self.set_height=size.height() self.set_width=size.width() returnsize.width(),size.height() defchose_screen(self): width,height=750,1370 desktop=QApplication.desktop() screen_count=desktop.screenCount() foriinrange(0,screen_count): rect=desktop.availableGeometry(i) s_width,s_height=rect.width(),rect.height() ifs_width>widthands_height>height: returnQRect(rect.left(),rect.top(),width,height) returnQRect(0,0,width,height) if__name__=='__main__': app=QApplication(sys.argv) win=MainWindow() win.show() app.exit(app.exec_())
2:收集页面高度,并计算分次截屏的次数和余量高度;实例化图片合并工具,设置定时器,超时信号发出后,执行exe_command;
defcheck_page(self): p_width,p_height=self.get_page_size() self.page,self.over_flow_size=divmod(p_height,self.height()) ifself.page==0: self.page=1 self.ssm=ScreenShotMerge(self.page,self.over_flow_size) self.timer=QTimer(self) self.timer.timeout.connect(self.exe_command) self.timer.setInterval(400) self.timer.start()
3:exe_command用来控制截图次数,并在每次截图完成后控制网页向下滑屏幕的高度;所有的页面都已截取时,完成图片合并。
defexe_command(self): ifself.page>0: self.screen_shot() self.run_js() elifself.page<0: self.timer.stop() self.ssm.image_merge() self.close() elifself.over_flow_size>0: self.screen_shot() self.page-=1 defrun_js(self): script=""" varscroll=function(dHeight){ vart=document.documentElement.scrollTop varh=document.documentElement.scrollHeight dHeight=dHeight||0 varcurrent=t+dHeight if(current>h){ window.scrollTo(0,document.documentElement.clientHeight) }else{ window.scrollTo(0,current) } } """ command=script+'\nscroll({})'.format(self.height()) self.browser.page().runJavaScript(command)
4:screen_shot在每次截图完成后将图片保存,并将图片对象由图片合并根据保存到列表中。
defscreen_shot(self): screen=QApplication.primaryScreen() winid=self.browser.winId() pix=screen.grabWindow(int(winid)) name='{}/temp.png'.format(self.ssm.root_path) pix.save(name) self.ssm.add_im(name)
5:截图合并工具,在每次截图完成后将图片对象保存,完成余量截图的重绘和截图的合并。
classScreenShotMerge(): def__init__(self,page,over_flow_size): self.im_list=[] self.page=page self.over_flow_size=over_flow_size self.get_path() defget_path(self): self.root_path=Path(__file__).parent.joinpath('temp') ifnotself.root_path.exists(): self.root_path.mkdir(parents=True) self.save_path=self.root_path.joinpath('merge.png') defadd_im(self,path): iflen(self.im_list)==self.page: im=self.reedit_image(path) else: im=Image.open(path) im.save('{}/{}.png'.format(self.root_path,len(self.im_list)+1)) self.im_list.append(im) defget_new_size(self): max_width=0 total_height=0 #计算合成后图片的宽度(以最宽的为准)和高度 forimginself.im_list: width,height=img.size ifwidth>max_width: max_width=width total_height+=height returnmax_width,total_height defimage_merge(self,): iflen(self.im_list)>1: max_width,total_height=self.get_new_size() #产生一张空白图 new_img=Image.new('RGB',(max_width-15,total_height),255) x=y=0 forimginself.im_list: width,height=img.size new_img.paste(img,(x,y)) y+=height new_img.save(self.save_path) print('截图成功:',self.save_path) else: obj=self.im_list[0] width,height=obj.size left,top,right,bottom=0,0,width,height box=(left,top,right,bottom) region=obj.crop(box) new_img=Image.new('RGB',(width,height),255) new_img.paste(region,box) new_img.save(self.save_path) print('截图成功:',self.save_path) defreedit_image(self,path): obj=Image.open(path) width,height=obj.size left,top,right,bottom=0,height-self.over_flow_size,width,height box=(left,top,right,bottom) region=obj.crop(box) returnregion
截图功能完整代码
#!/usr/bin/envpython #-*-coding:UTF-8-*- #Author:Leslie-x importsys fromPyQt5.QtCoreimport* fromPyQt5.QtWidgetsimport* fromPyQt5.QtWebEngineWidgetsimport* fromPILimportImage frompathlibimportPath classScreenShotMerge(): def__init__(self,page,over_flow_size): self.im_list=[] self.page=page self.over_flow_size=over_flow_size self.get_path() defget_path(self): self.root_path=Path(__file__).parent.joinpath('temp') ifnotself.root_path.exists(): self.root_path.mkdir(parents=True) self.save_path=self.root_path.joinpath('merge.png') defadd_im(self,path): iflen(self.im_list)==self.page: im=self.reedit_image(path) else: im=Image.open(path) im.save('{}/{}.png'.format(self.root_path,len(self.im_list)+1)) self.im_list.append(im) defget_new_size(self): max_width=0 total_height=0 #计算合成后图片的宽度(以最宽的为准)和高度 forimginself.im_list: width,height=img.size ifwidth>max_width: max_width=width total_height+=height returnmax_width,total_height defimage_merge(self,): iflen(self.im_list)>1: max_width,total_height=self.get_new_size() #产生一张空白图 new_img=Image.new('RGB',(max_width-15,total_height),255) x=y=0 forimginself.im_list: width,height=img.size new_img.paste(img,(x,y)) y+=height new_img.save(self.save_path) print('截图成功:',self.save_path) else: obj=self.im_list[0] width,height=obj.size left,top,right,bottom=0,0,width,height box=(left,top,right,bottom) region=obj.crop(box) new_img=Image.new('RGB',(width,height),255) new_img.paste(region,box) new_img.save(self.save_path) print('截图成功:',self.save_path) defreedit_image(self,path): obj=Image.open(path) width,height=obj.size left,top,right,bottom=0,height-self.over_flow_size,width,height box=(left,top,right,bottom) region=obj.crop(box) returnregion classMainWindow(QMainWindow): def__init__(self,parent=None): super(MainWindow,self).__init__(parent) self.setWindowTitle('易哈佛') self.temp_height=0 self.setWindowFlag(Qt.WindowMinMaxButtonsHint,False)#禁用最大化,最小化 #self.setWindowFlag(Qt.WindowStaysOnTopHint,True)#窗口顶置 self.setWindowFlag(Qt.FramelessWindowHint,True)#窗口无边框 defurlScreenShot(self,url): self.browser=QWebEngineView() self.browser.load(QUrl(url)) geometry=self.chose_screen() self.setGeometry(geometry) self.browser.loadFinished.connect(self.check_page) self.setCentralWidget(self.browser) defget_page_size(self): size=self.browser.page().contentsSize() self.set_height=size.height() self.set_width=size.width() returnsize.width(),size.height() defchose_screen(self): width,height=750,1370 desktop=QApplication.desktop() screen_count=desktop.screenCount() foriinrange(0,screen_count): rect=desktop.availableGeometry(i) s_width,s_height=rect.width(),rect.height() ifs_width>widthands_height>height: returnQRect(rect.left(),rect.top(),width,height) returnQRect(0,0,width,height) defcheck_page(self): p_width,p_height=self.get_page_size() self.page,self.over_flow_size=divmod(p_height,self.height()) ifself.page==0: self.page=1 self.ssm=ScreenShotMerge(self.page,self.over_flow_size) self.timer=QTimer(self) self.timer.timeout.connect(self.exe_command) self.timer.setInterval(400) self.timer.start() defexe_command(self): ifself.page>0: self.screen_shot() self.run_js() elifself.page<0: self.timer.stop() self.ssm.image_merge() self.close() elifself.over_flow_size>0: self.screen_shot() self.page-=1 defrun_js(self): script=""" varscroll=function(dHeight){ vart=document.documentElement.scrollTop varh=document.documentElement.scrollHeight dHeight=dHeight||0 varcurrent=t+dHeight if(current>h){ window.scrollTo(0,document.documentElement.clientHeight) }else{ window.scrollTo(0,current) } } """ command=script+'\nscroll({})'.format(self.height()) self.browser.page().runJavaScript(command) defscreen_shot(self): screen=QApplication.primaryScreen() winid=self.browser.winId() pix=screen.grabWindow(int(winid)) name='{}/temp.png'.format(self.ssm.root_path) pix.save(name) self.ssm.add_im(name) if__name__=='__main__': url='http://blog.sina.com.cn/lm/rank/focusbang//' app=QApplication(sys.argv) win=MainWindow() win.urlScreenShot(url) win.show() app.exit(app.exec_())
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。