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_())
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。