精华内容
下载资源
问答
  • 网页截图
    千次阅读
    2021-03-05 16:26:10

    一、环境介绍

    (1)版本介绍

    python版本:3.7
    pip版本:20.0.1
    pyqt5版本:5.15.3
    PIL版本:8.1.1
    selenium版本:2.48.0 (推荐使用,3.*版本之后会报错)
    
    **开发工具:pycharm**
    需要用到的工具:phantomjs.exe、chromedriver.exe
    

    (2)安装

    # 不指定版本
    pip install pyqt5
    pip install pillow
    pip install selenium
    # 指定安装版本
    pip install pyqt5==版本号
    pip install pillow==版本号
    pip install selenium==2.48.0(推荐使用,3.*版本之后会报错)
    

    二、实现过程以及功能介绍

    本人将通过度娘收集到的三种截图方式做了一个简单的集合分装,只需要传入相应的参数即可。

    (1)pyqt5模块实现

    文件路径:venv1/Screenshot/Driver/MainWindow.py

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtWebEngineWidgets import *
    from PIL import Image,ImageGrab
    from Screenshot.Driver import BaseDriver,ImageMerge
    import traceback
    
    
    class MainWindow(QMainWindow, BaseDriver):
    
        def __init__(self, parent=None):
            self.app = QApplication(sys.argv)
            super(MainWindow, self).__init__()
            self.setWindowTitle('截图')
            # self.temp_height = 0
            self.setWindowFlag(Qt.WindowMinMaxButtonsHint, False) # 禁用最大化,最小化
            # self.setWindowFlag(Qt.WindowStaysOnTopHint, True) # 窗口顶置
            self.setWindowFlag(Qt.FramelessWindowHint,True) # 窗口无边框
    
        def shotScreen(self):
            try:
                print('MainWindow->shotScreen', 'url=' + self.win_url)
                self.getTempPath(isClean=True)
                # 创建浏览器实例
                self.browser = QWebEngineView()
                self.winId = self.browser.winId()
                # 加载页面
                self.browser.load(QUrl(self.win_url))
                # 设置中心窗口
                self.setCentralWidget(self.browser)
                # 设置截图窗口
                geometry = self.chose_screen()
                self.setGeometry(geometry)
                # 页面加载完成后执行 check_page回调
                res = self.browser.loadFinished.connect(self.check_page)
                self.show()
                self.app.exit(self.app.exec_())
            except:
                self.checkShotCallback(file=None,error=traceback.format_exc())
            return self
    
        # 获取页面的宽高
        def get_page_size(self):
            print('MainWindow->get_page_size')
            size = self.browser.page().contentsSize()
            self.set_height = size.height()
            self.set_width  = size.width()
            return size.width(), size.height()
    
        # 选择桌面窗口
        def chose_screen(self):
            print('MainWindow->chose_screen')
            # 设置窗口的宽度和高度
            desktop = QApplication.desktop()
            screen_count = desktop.screenCount()
            # print('screen_count=',screen_count)
            for i in range(0, screen_count):
                rect = desktop.availableGeometry(i)
                s_width, s_height = rect.width(), rect.height()
                if (self.win_width and self.win_height):
                    if (s_width >self.win_width and s_height > self.win_height):
                        if(not self.win_x and not self.win_y):
                            self.win_x,self.win_y = rect.left(),rect.top()
                        break
                else:
                    if (not self.win_width or s_width > self.win_width):
                        self.win_width = s_width
                    if (not self.win_height or s_height > self.win_height):
                        self.win_height = s_height
            self.bbox = (self.win_x, self.win_y, self.win_width, self.win_height)
            return QRect(self.win_x, self.win_y, self.win_width, self.win_height)
    
        def check_page(self):
            print('MainWindow->check_page')
            # 获取页面的宽度和高度
            p_width, p_height = self.get_page_size()
            # 计算页数, 页面高度%窗口高度
            self.page, self.over_flow_size = divmod(p_height, self.height())
            print('page='+str(self.page))
            self.shotPage = 0
            if(self.page == 0):
                self.page = 1
            # 创建截图合并实例
            self.ssm = ImageMerge.ImageMerge(save_path=self.getSavePath())
            # 创建定时器
            self.timer = QTimer(self)
            # 定时执行 exe_command 回调
            self.timer.timeout.connect(self.exe_command)
            # 设置定时间隔,单位:ms
            self.timer.setInterval(2000)
            # 启动定时器
            self.timer.start()
            return self
    
        # 执行截图判断
        def exe_command(self):
            print('MainWindow->exe_command')
            if(self.page > 0):
                # 截图后 滚动页面至下一页
                self.screen_shot().run_js()
            else:
                # 关闭定时器
                self.timer.stop()
                if(self.over_flow_size > 0):
                    # 截图
                    self.screen_shot()
                # 合并所有截图,
                file_path, new_img = self.ssm.image_merge(filename=self.image_name)
                # 关闭窗口
                self.close()
                self.checkShotCallback(file=file_path, error=None)
            self.page -= 1
            self.shotPage += 1
            return self
    
        # 执行js代码
        def run_js(self):
            print('MainWindow->run_js')
            script = """
                var scroll = function(dHeight){
                    var t = document.documentElement.scrollTop;
                    var h = document.documentElement.scrollHeight;
                    var ch = document.documentElement.clientHeight;
                    dHeight = dHeight || 0;
                    var current = t + dHeight;
                    if(current > h){
                        window.scrollTo(0, ch)
                    }else{
                        window.scrollTo(0, current)
                    }
                }
            """
            height = self.height()
            command = script + '\n scroll({})'.format(height)
            self.browser.page().runJavaScript(command)
            return self
    
        # 截屏
        def screen_shot(self):
            print('MainWindow->screen_shot')
            # 截图保存路径
            path = self.temp_path
            file_path = str(path.joinpath("{}_{}".format(self.shotPage, self.image_name)))
            # 创建 截图工具实例
            im = ImageGrab.grab(bbox=self.bbox)
            # 保存截图
            im.save(file_path)
            self.ssm.add_im(file_path)
            return self
    

    (2)selenium模块实现

    文件路径:venv/Screenshot/Driver/selenium.py

    from selenium import webdriver
    import Screenshot
    import traceback
    
    class Selenium(Screenshot.Driver.BaseDriver):
    
        def __init__(self):
            print('Selenium->__init__')
            pass
    
        # 通过phantomjs隐式截图
        def shotScreenByPhantomjs(self):
            print('Selenium->shotScreenByPhantomjs')
            picName = '{}/{}'.format(self.getSavePath(), self.image_name)
            brower = webdriver.PhantomJS(
                executable_path='E:/wens/CompanyProject/python_reptile/venv1/Screenshot/Tools/phantomjs.exe')
            if (self.win_width and self.win_height):
                brower.set_window_size(width=self.win_width, height=self.win_height)
            else:
                brower.maximize_window()
            brower.get(self.win_url)
            brower.get_screenshot_as_file(picName)
            brower.close()
            self.checkShotCallback(file=picName, error=None)
            return self
    
        # 利用谷歌浏览器截图
        def shotScreenByChrome(self):
            print('Selenium->shotScreenByChrome')
            picName = '{}/{}'.format(self.getSavePath(), self.image_name)
            driver = webdriver.Chrome(r"E:\wens\CompanyProject\python_reptile\venv1\Screenshot\Tools\chromedriver.exe")
            if (self.win_width and self.win_height):
                driver.set_window_size(width=self.win_width, height=self.win_height)
            else:
                driver.maximize_window()
            driver.get(self.win_url)
            driver.get_screenshot_as_file(picName)
            driver.close()
            self.checkShotCallback(file=picName,error=None)
            return self
    
        def shotScreen(self):
            try:
                print('Selenium->shotScreen')
                Screenshot.switch(self.shot_driver, {
                    Screenshot.Screenshot.sDriver_Chrome: self.shotScreenByChrome,
                    Screenshot.Screenshot.sDriver_Phantomjs: self.shotScreenByPhantomjs,
                    'default': self.shotScreenByPhantomjs
                })
            except:
                self.checkShotCallback(file=None, error=traceback.format_exc())
            return self
    

    (3)图片合并处理

    文件路径:venv/Screenshot/Driver/ImageMerge.py

    from pathlib import Path
    from PIL import Image
    
    class ImageMerge():
    
        root_path = None
    
        save_path = None
    
        im_list = []
    
    
        def __init__(self, save_path=None):
            print('ImageMerge->__init__')
            self.save_path = save_path
            self.im_list = []
            self.get_path()
    
        def get_path(self):
            print('ImageMerge->get_path')
            self.root_path = Path(__file__).parent.parent
            if(not self.save_path):
                self.save_path = self.root_path.joinpath('image/merge')
            if (not self.save_path.exists()):
                self.save_path.mkdir(parents=True)
            return self
    
        def add_im(self, path):
            print('ImageMerge.add_im', path)
            im = Image.open(path)
            self.im_list.append(im)
            return self
    
        def get_new_size(self):
            print('ImageMerge->get_new_size')
            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, filename):
            print('ImageMerge->image_merge')
            file_path = '{}/{}'.format(self.save_path, filename)
            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(file_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(file_path)
            return file_path, new_img
    

    (4)基类BaseDriver

    文件路径:venv/Screenshot/Driver/__init__.py

    import shutil
    from pathlib import Path
    
    class BaseDriver():
        win_width = None
    
        win_height = None
    
        win_url = None
    
        image_path = None
    
        temp_path = None
    
        image_name = None
    
        shot_driver = None
    
        shot_callback = None
    
        win_x = 0
    
        win_y = 0
    
        def setWindowPosition(self, x, y):
            self.win_x = x
            self.win_y = y
            return self
    
        def setWindowSize(self, width, height):
            print('BaseDriver->setWindowSize')
            self.win_width = width
            self.win_height = height
            return self
    
        def setSavePath(self, save_path):
            print('BaseDriver->setSavePath')
            self.image_path = save_path
            return self
    
        def setTempPath(self, temp_path):
            self.temp_path = temp_path
            return self
    
        def url(self, url:str):
            print('BaseDriver->url')
            self.win_url = url
            return self
    
        def filename(self, filename):
            print('BaseDriver->filename')
            self.image_name = filename
            return self
    
        def driver(self, driver):
            print('BaseDriver->driver')
            self.shot_driver = driver
            return self
    
        def shotCallback(self, callback):
            print('BaseDriver->shotCallback')
            self.shot_callback = callback
            return self
    
        def checkShotCallback(self, file=None, error=None):
            if (self.shot_callback):
                self.shot_callback({
                    'file': file,
                    'error': error
                })
            return self
    
        def getSavePath(self):
            print('MainWindow->getSavePath')
            if (not self.image_path or self.image_path is None):
                self.image_path = Path(__file__).parent.parent.joinpath('image/merge')
            if (not self.image_path.exists()):
                self.image_path.mkdir(parents=True)
            return self.image_path
    
        def getTempPath(self, isClean=False):
            print('MainWindow->getTempPath')
            if(not self.temp_path or self.temp_path is None):
                self.temp_path = Path(__file__).parent.parent.joinpath('image/temp')
            if(not self.temp_path.exists()):
                self.temp_path.mkdir(parents=True)
            elif(isClean):
                shutil.rmtree(self.temp_path)
                self.temp_path.mkdir(parents=True)
            return self.temp_path
    
        def shotScreen(self):
            print('BaseDriver->shotScreen')
            return self
    

    (5)集合控制器

    文件路径:venv/Screenshot/__init__.py

    from Screenshot.Driver import selenium,ImageMerge,BaseDriver,MainWindow
    from pathlib import Path
    import traceback
    
    
    class Screenshot():
    
        pModel_QT5 = 1
    
        pModel_Selenium = 2
    
        sDriver_Phantomjs = 1
    
        sDriver_Chrome = 2
    
        win_url = ''
    
        win_width = None
    
        win_height = None
    
        save_path = None
    
        temp_path = None
    
        shot_pModel = pModel_Selenium
    
        shot_driver = sDriver_Phantomjs
    
        shot_callback = None
    
        win_x = 0
    
        win_y = 0
    
        def __init__(self):
            print('ScreenShot->__init__')
            pass
    
        def setWindowPosition(self, x, y):
            self.win_x = x
            self.win_y = y
            return self
    
        def url(self, url):
            print('Screenshot->url')
            self.win_url = url
            return self
    
        def pModel(self, model):
            print('Screenshot->pmodel')
            self.shot_pModel = model
            return self
    
        def driver(self, driver):
            print('Screenshot->driver')
            self.shot_driver = driver
            return  self
    
        def setWindowSize(self, width , height):
            print('Screenshot->setWindowSize')
            self.win_width = width
            self.win_height = height
            return self
    
        def savePath(self, path):
            print('Screenshot->savePath')
            self.save_path = Path(path)
            if(not self.save_path.exists()):
                self.save_path.mkdir(parents=True)
            return self
    
        def selenium(self):
            print('Screenshot->selenium')
            return selenium.Selenium()
    
        def pyqt5(self):
            print('Screenshot->pyqt5')
            obj = MainWindow.MainWindow()
            return obj
    
        def shotCallback(self, callback):
            print('Screenshot->shotCallback')
            self.shot_callback = callback
            return self
    
    
        def getDriver(self):
            print('Screenshot->getDriver')
            result = switch(self.shot_pModel, {
                self.pModel_QT5: self.pyqt5,
                self.pModel_Selenium: self.selenium,
                'default': self.selenium
            })
            return result
    
        def save(self, filename):
            print('Screenshot->save')
            return self.getDriver()\
                .setWindowPosition(x=self.win_x, y=self.win_y)\
                .url(self.win_url)\
                .driver(self.shot_driver)\
                .setWindowSize(width=self.win_width, height=self.win_height)\
                .filename(filename)\
                .setSavePath(self.getSavePath())\
                .setTempPath(temp_path=self.getTempPath())\
                .shotCallback(self.shot_callback)\
                .shotScreen()
    
        def getSavePath(self):
            print('Screenshot->getSavePath')
            if(not self.save_path or self.save_path is None):
                self.save_path = Path(__file__).parent.joinpath('image/merge')
            if(not self.save_path.exists()):
                self.save_path.mkdir(parents=True)
            return self.save_path
    
        def getTempPath(self):
            print('Screenshot->getTempPath')
            path = Path(__file__).parent.joinpath('image/temp')
            if(not path.exists()):
                path.mkdir(parents=True)
            return path
    
    
    def switch(key, options:dict):
        print('switch')
        item = options.get(key, options.get('default'));
        if (hasattr(item, '__call__')):
            return item()
        else:
            return item
    

    (6)实例·例子

    文件路径:main.py

    from Screenshot import *
    from pathlib import Path
    url = 'http://blog.sina.com.cn/lm/rank/focusbang//'
    save_path = Path(__file__).parent.joinpath('shotScreen')
    
    def shotCallback(res):
        print('file_path',res)
    Screenshot()\
        .setWindowPosition(x=30, y=0)\
        .url(url).setWindowSize(1000, 800)\
        .savePath(save_path)\
        .shotCallback(shotCallback)\
        .pModel(model=Screenshot.pModel_Selenium)\
        .driver(driver=Screenshot.sDriver_Phantomjs)\
        .save(filename='screen.png')
    

    (7)截图效果在这里插入图片描述

    三、总结与资源

    (1)截图方式总结

    以上三总截图方案中只有phantomjs截图是隐式截图,其他两种方式(pyqt5和chrome)截图都是显示截图。

    隐式截图:无法看到截图界面,用户在桌面的操作不会影像截图效果;
    显示截图:执行过程中,程序会调用浏览器在桌面打开一个浏览器窗口,然后通过截屏实现截图功能;
    

    显示截图中,pyqt5做了智能滚动截图然后合并处理,chrome只是单纯截图网页显示部分。如果网页内容过长,有滚动条的推荐使用隐式截图(phantomjs)和pyqt5方式截图。

    (2)资源下载

    如需要下载资源参考:python实现网页截图(v1.0.0).rar

    更多相关内容
  • WebCapture源码,采用VB.net编写的一款网页截图工具,可以捕获整个网页,并将网页保存成图片格式。这是一款来自国外的网页截屏工具,源代码完整,运行于VS环境,运行的界面效果如图所示。在文档URL中输入网址,然后...
  • C#实现网页截图功能

    2021-01-20 06:49:53
    网页截图是很常见的实用功能,今天就为大家共享一个实现浏览器截图的代码,主要程序代码如下所示: private void Form_Load(object sender, EventArgs e) { //接收web url string colle = string.Empty; string ...
  • 主要介绍了JavaScript实现网页截图功能,本文介绍了2款实现JavaScript截图的开源组件,一个是Canvas2Image,一个是html2canvas,需要的朋友可以参考下
  • 主要为大家详细介绍了python实现自动网页截图并裁剪图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 捕捉网页截图,编辑并将它们保存为PDF,JPEG,GIF,PNG或BMP;上传,打印,在Photoshop中打开,复制到剪贴板或电子邮件
  • 主要介绍了命令行下的2款网页截图工具推荐,分别是针对IE浏览器的IECapt和针对Firefox浏览器的PageSaver,需要的朋友可以参考下
  • 方便快捷地截取整个网页,并保存为图像。这是第一个可以截取整个页面的扩展。 此扩展程序为您提供了一种获取当前浏览器窗口的全屏屏幕截图的简单方法。 单击扩展程序图标,观看扩展程序以截取页面各部分的屏幕截图,...
  • 两种方式实现网页快照,快速截屏网页,不必打开浏览器
  • java调用phantomJs进行网页截图源码,有需要的朋友自行下载
  • 本文实例讲述了C#实现的滚动网页截图功能。分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using ...
  • js网页截图andjQuery前端截图源码 对于前端截图功能值得一看
  • 网页截图工具
  • FireShot 是一款网页截屏工具,最出色的功能是可以自动滚屏,以截取整个网页,并且可以编辑和注释截取的图片。支出一键输出保存为PDF,JPEG,GIF,PNG或BMP,或上传,打印,在Photoshop中打开,复制到剪贴板或电子...
  • java 网页截图

    2017-09-28 10:15:18
    java 网页截图,实现打开指定url页面,完成截图,并把图片保存到指定路径
  • java实现网页截图技术

    2019-04-20 01:05:41
    NULL 博文链接:https://happywaterlife.iteye.com/blog/1884245
  • 稻草网页截图工具是一个免费的完整网页截图工具,它可以一键截取整个网页,保存为图片 使用简单:输入网址--打开网页--截图,就完成了
  • linux或windows下对网页截图开发所使用的第三方工具总结
  • crop-page:网页截图服务

    2021-05-31 03:39:04
    网页截图服务 示例 示例代码 http://49.233.2.233:3002/crop?src=https://jd.com&renderWidth=1000&width=1000 完整参数说明 src<String>: 必选,截图的页面地址(encodeURIComponent),例:http://seejs.me ...
  • 是一个用VC写的可以嵌套在网页里面的插件,实现截图功能
  • 访问一些网页,并且实时截图网页列表以php数组形式存在
  • 网页截图-crx插件

    2021-03-20 09:03:43
    截取网页为图片,支持窗口截图,区域截图和整个网页截图三种方式。支持水平和垂直翻页截取超大网页,新版引进自动截图保存功能。 “屏幕捕获”是AdriàVilanovaMartínez(又名@ avm99963)维护的原始扩展“屏幕捕获...
  • 1、这是一款捕捉网页截图插件 2、支持编辑和注释您的截图 3、收费只是想让你们知道资源得来不易
  • 一屏截图.zip,一屏截图,SiteShot.exe
  • 后台网页截图

    2015-12-28 23:25:27
    后台网页截图、本代码用的WIN32实现的WEBBrower后台截图。
  • python网页截图程序

    2018-03-07 20:51:40
    使用python2.7和selenium完成打开网页,移动滚动条到标签位置,然后截屏成png图片。
  • 网页截图插件 配合Puppeteer完成网页截图,。 预览 使用方法 ES6 Module import CropInPage from 'crop-in-page'; const cropper = new CropInPage(); cropper.init(); // 即可打开截图界面 AMD Module const ...
  • 本文实例讲述了php通过执行CutyCapt命令实现网页截图的方法。分享给大家供大家参考,具体如下: 用php使用exec执行命令 PS.默认情况下exec函数是禁用的,打开php.ini检查disable_function是否包含这个还是,有就去除...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,133
精华内容 33,253
关键字:

网页截图

友情链接: 6012082.rar