博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python实现网页截图(PyQT5)
阅读量:6076 次
发布时间:2019-06-20

本文共 10893 字,大约阅读时间需要 36 分钟。

方案说明

功能要求:实现网页加载后将页面截取成长图片

涉及模块:PyQT5 PIL
逻辑说明:

1:完成窗口设置,利用PyQT5 QWebEngineView加载网页地址,待网页加载完成后,调用check_pag;
class MainWindow(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)  # 窗口无边框    def urlScreenShot(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)    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(), rect.top(), width, height)        return QRect(0, 0, width, height)if __name__ == '__main__':    app = QApplication(sys.argv)    win = MainWindow()    win.show()    app.exit(app.exec_())

2:收集页面高度,并计算分次截屏的次数和余量高度;实例化图片合并工具,设置定时器,超时信号发出后,执行exe_command;

def check_page(self):        p_width, p_height = self.get_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.timer.timeout.connect(self.exe_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 = screen.grabWindow(int(winid))        name = '{}/temp.png'.format(self.ssm.root_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        self.get_path()    def get_path(self):        self.root_path = Path(__file__).parent.joinpath('temp')        if not self.root_path.exists():            self.root_path.mkdir(parents=True)        self.save_path = self.root_path.joinpath('merge.png')    def add_im(self, path):        if len(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)    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 = self.get_new_size()            # 产生一张空白图            new_img = Image.new('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 = 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)    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 = obj.crop(box)        return region

截图功能完整代码

#!/usr/bin/env python# -*- coding:UTF-8 -*-# Author:Leslie-ximport sysfrom PyQt5.QtCore import *from PyQt5.QtWidgets import *from PyQt5.QtWebEngineWidgets import *from PIL import Imagefrom pathlib import Pathclass ScreenShotMerge():    def __init__(self, page, over_flow_size):        self.im_list = []        self.page = page        self.over_flow_size = over_flow_size        self.get_path()    def get_path(self):        self.root_path = Path(__file__).parent.joinpath('temp')        if not self.root_path.exists():            self.root_path.mkdir(parents=True)        self.save_path = self.root_path.joinpath('merge.png')    def add_im(self, path):        if len(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)    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 = self.get_new_size()            # 产生一张空白图            new_img = Image.new('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 = 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)    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 = obj.crop(box)        return regionclass MainWindow(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)  # 窗口无边框    def urlScreenShot(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)    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(), rect.top(), width, height)        return QRect(0, 0, width, height)    def check_page(self):        p_width, p_height = self.get_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.timer.timeout.connect(self.exe_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 = 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_())
View Code

 

转载于:https://www.cnblogs.com/li1992/p/10446971.html

你可能感兴趣的文章
搭建一个通用的脚手架
查看>>
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
查看>>
开源磁盘加密软件VeraCrypt教程
查看>>
本地vs云:大数据厮杀的最终幸存者会是谁?
查看>>
阿里云公共镜像、自定义镜像、共享镜像和镜像市场的区别 ...
查看>>
shadowtunnel v1.7 发布:新增上级负载均衡支持独立密码
查看>>
Java线程:什么是线程
查看>>
mysql5.7 创建一个超级管理员
查看>>
【框架整合】Maven-SpringMVC3.X+Spring3.X+MyBatis3-日志、JSON解析、表关联查询等均已配置好...
查看>>
要想成为高级Java程序员需要具备哪些知识呢?
查看>>
带着问题去学习--Nginx配置解析(一)
查看>>
onix-文件系统
查看>>
java.io.Serializable浅析
查看>>
我的友情链接
查看>>
多线程之线程池任务管理通用模板
查看>>
CSS3让长单词与URL地址自动换行——word-wrap属性
查看>>
CodeForces 580B Kefa and Company
查看>>
开发规范浅谈
查看>>
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
查看>>
鼠标增强软件StrokeIt使用方法
查看>>