⽤Python五步实现⽹页截图
⽅案说明
功能要求:实现⽹页加载后将页⾯截取成长图⽚
涉及模块:PyQT5 PIL
逻辑说明:
1:完成窗⼝设置,利⽤PyQT5 QWebEngineView加载⽹页地址,待⽹页加载完成后,调⽤check_pag;
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle('易哈佛')
self.setWindowFlag(Qt.WindowMinMaxButtonsHint, False) # 禁⽤最⼤化,最⼩化
# self.setWindowFlag(Qt.WindowStaysOnTopHint, True) # 窗⼝顶置
self.setWindowFlag(Qt.FramelessWindowHint, True) # 窗⼝⽆边框
def urlScreenShot(self, url):
self.browser = QWebEngineView()
self.browser.load(QUrl(url))
geometry = self.chose_screen()
self.setGeometry(geometry)
self.t(self.check_page)
self.setCentralWidget(self.browser)
def get_page_size(self):
size = self.browser.page().contentsSize()
self.set_height = size.height()
self.set_width = size.width()
return size.width(), size.height()
def chose_screen(self):
width, height = 750, 1370
desktop = QApplication.desktop()
screen_count = desktop.screenCount()
for i in range(0, screen_count):
rect = desktop.availableGeometry(i)
s_width, s_height = rect.width(), rect.height()
if s_width > width and s_height > height:
return QRect(rect.left(), p(), width, height)
return QRect(0, 0, width, height)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
<_())
2:收集页⾯⾼度,并计算分次截屏的次数和余量⾼度;实例化图⽚合并⼯具,设置定时器,超时信号发出后,执⾏exe_command;def check_page(self):
p_width, p_height = _page_size()
self.page, self.over_flow_size = divmod(p_height, self.height())
if self.page == 0:
self.page = 1
self.ssm = ScreenShotMerge(self.page, self.over_flow_size)
self.timer = QTimer(self)
self._command)
self.timer.setInterval(400)
self.timer.start()
3:exe_command⽤来控制截图次数,并在每次截图完成后控制⽹页向下滑屏幕的⾼度;所有的页⾯都已截取时,完成图⽚合并。def exe_command(self):
if self.page > 0:
self.screen_shot()
self.run_js()
elif self.page < 0:
self.timer.stop()
self.ssm.image_merge()
self.close()
elif self.over_flow_size > 0:
self.screen_shot()
self.page -= 1
def run_js(self):
script = """
var scroll = function (dHeight) {
var t = document.documentElement.scrollTop
var h = document.documentElement.scrollHeight
dHeight = dHeight || 0
var current = t + dHeight
if (current > h) {
window.scrollTo(0, document.documentElement.clientHeight)
} else {
window.scrollTo(0, current)
}
}
"""
command = script + '\n scroll({})'.format(self.height())
self.browser.page().runJavaScript(command)
4:screen_shot在每次截图完成后将图⽚保存,并将图⽚对象由图⽚合并根据保存到列表中。def screen_shot(self):
screen = QApplication.primaryScreen()
winid = self.browser.winId()
pix = abWindow(int(winid))
name = '{}/temp.png'.format(_path)
pix.save(name)
self.ssm.add_im(name)
5:截图合并⼯具,在每次截图完成后将图⽚对象保存,完成余量截图的重绘和截图的合并。class ScreenShotMerge():
def __init__(self, page, over_flow_size):
self.im_list = []
self.page = page
self.over_flow_size = over_flow_size
<_path()
def get_path(self):
<_path = Path(__file__).parent.joinpath('temp')
if _ists():
<_path.mkdir(parents=True)
self.save_path = _path.joinpath('merge.png')
def add_im(self, path):
if len(self.im_list) == self.page:
im = dit_image(path)
else:
im = Image.open(path)
im.save('{}/{}.png'._path, len(self.im_list) + 1))
self.im_list.append(im)
def get_new_size(self):
max_width = 0
total_height = 0
# 计算合成后图⽚的宽度(以最宽的为准)和⾼度
for img in self.im_list:
width, height = img.size
if width > max_width:
max_width = width
total_height += height
return max_width, total_height
def image_merge(self, ):
if len(self.im_list) > 1:
max_width, total_height = _new_size()
# 产⽣⼀张空⽩图
new_img = w('RGB', (max_width - 15, total_height), 255)
x = y = 0
for img in self.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 = p(box)
new_img = w('RGB', (width, height), 255)
new_img.paste(region, box)
new_img.save(self.save_path)
print('截图成功:', self.save_path)
def reedit_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 = p(box)
return region
截图功能完整代码
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
#Python学习交流:778463939
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PIL import Image
from pathlib import Path
class ScreenShotMerge():
def __init__(self, page, over_flow_size):
self.im_list = []
self.page = page
self.over_flow_size = over_flow_size
<_path()
def get_path(self):
<_path = Path(__file__).parent.joinpath('temp')
if _ists():
<_path.mkdir(parents=True)
self.save_path = _path.joinpath('merge.png')
def add_im(self, path):
if len(self.im_list) == self.page:
im = dit_image(path)
else:
im = Image.open(path)
im.save('{}/{}.png'._path, len(self.im_list) + 1))
self.im_list.append(im)
def get_new_size(self):
max_width = 0
total_height = 0
# 计算合成后图⽚的宽度(以最宽的为准)和⾼度
for img in self.im_list:
width, height = img.size
if width > max_width:
max_width = width
total_height += height
return max_width, total_height
def image_merge(self, ):
if len(self.im_list) > 1:
max_width, total_height = _new_size()
# 产⽣⼀张空⽩图
new_img = w('RGB', (max_width - 15, total_height), 255)
x = y = 0
for img in self.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 = p(box)
new_img = w('RGB', (width, height), 255)
new_img.paste(region, box)
new_img.save(self.save_path)
print('截图成功:', self.save_path)
def reedit_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 = p(box)
return region
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle('易哈佛')
self.setWindowFlag(Qt.WindowMinMaxButtonsHint, False) # 禁⽤最⼤化,最⼩化 # self.setWindowFlag(Qt.WindowStaysOnTopHint, True) # 窗⼝顶置
self.setWindowFlag(Qt.FramelessWindowHint, True) # 窗⼝⽆边框
def urlScreenShot(self, url):
self.browser = QWebEngineView()
self.browser.load(QUrl(url))
geometry = self.chose_screen()
self.setGeometry(geometry)
self.t(self.check_page)
self.setCentralWidget(self.browser)
def get_page_size(self):
size = self.browser.page().contentsSize()
self.set_height = size.height()
self.set_width = size.width()
return size.width(), size.height()
def chose_screen(self):
width, height = 750, 1370
desktop = QApplication.desktop()
screen_count = desktop.screenCount()
for i in range(0, screen_count):
rect = desktop.availableGeometry(i)
s_width, s_height = rect.width(), rect.height()
if s_width > width and s_height > height:
return QRect(rect.left(), p(), width, height)
return QRect(0, 0, width, height)
def check_page(self):
p_width, p_height = _page_size()
self.page, self.over_flow_size = divmod(p_height, self.height())
if self.page == 0:
self.page = 1
self.ssm = ScreenShotMerge(self.page, self.over_flow_size)
self.timer = QTimer(self)
self._command)
self.timer.setInterval(400)
self.timer.start()
def exe_command(self):
if self.page > 0:
self.screen_shot()
self.run_js()
elif self.page < 0:
self.timer.stop()
self.ssm.image_merge()
self.close()
elif self.over_flow_size > 0:
self.screen_shot()
self.page -= 1
def run_js(self):
script = """
var scroll = function (dHeight) {
var t = document.documentElement.scrollTop
var h = document.documentElement.scrollHeight
dHeight = dHeight || 0
var current = t + dHeight
if (current > h) {
window.scrollTo(0, document.documentElement.clientHeight) } else {
window.scrollTo(0, current)
}
}
"""
command = script + '\n scroll({})'.format(self.height())
self.browser.page().runJavaScript(command)
def screen_shot(self):
screen = QApplication.primaryScreen()
winid = self.browser.winId()
pix = abWindow(int(winid))
name = '{}/temp.png'.format(_path)
pix.save(name)
self.ssm.add_im(name)
if __name__ == '__main__':
url = 'blog.sina/lm/rank/focusbang//'
app = QApplication(sys.argv)
win = MainWindow()
win.urlScreenShot(url)
win.show()
<_())
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论