目录

  • 一、环境介绍
    • (1)版本介绍
    • (2)安装
  • 二、实现过程以及功能介绍
    • (1)pyqt5模块实现
    • (2)selenium模块实现
    • (3)图片合并处理
    • (4)基类BaseDriver
    • (5)集合控制器
    • (6)实例·例子
    • (7)截图效果![在这里插入图片描述](https://img-blog.csdnimg.cn/20210305175922697.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4NDIxMjI2,size_16,color_FFFFFF,t_70#pic_center)
  • 三、总结与资源
    • (1)截图方式总结
    • (2)资源下载

一、环境介绍

(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 tracebackclass MainWindow(QMainWindow, BaseDriver):def __init__(self, parent=None):self.app = QApplication(sys.argv)super(MainWindow, self).__init__()self.setWindowTitle('截图')# self.temp_height = 0self.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()breakelse:if (not self.win_width or s_width > self.win_width):self.win_width = s_widthif (not self.win_height or s_height > self.win_height):self.win_height = s_heightself.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 = 0if(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)# 设置定时间隔,单位:msself.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 -= 1self.shotPage += 1return 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_pathfile_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 tracebackclass 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 selfdef 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 Imageclass ImageMerge():root_path = Nonesave_path = Noneim_list = []def __init__(self, save_path=None):print('ImageMerge->__init__')self.save_path = save_pathself.im_list = []self.get_path()def get_path(self):print('ImageMerge->get_path')self.root_path = Path(__file__).parent.parentif(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 selfdef add_im(self, path):print('ImageMerge.add_im', path)im = Image.open(path)self.im_list.append(im)return selfdef get_new_size(self):print('ImageMerge->get_new_size')max_width = 0total_height = 0# 计算合成后图片的宽高(以最宽的为准)和高度for img in self.im_list:width, height = img.sizeif(width > max_width):max_width = widthtotal_height += heightreturn max_width, total_heightdef 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 = 0for img in self.im_list:width, height = img.sizenew_img.paste(img, (x, y))y += heightnew_img.save(file_path)else:obj = self.im_list[0]width, height =  obj.sizeleft, top, right, bottom = 0, 0, width, heightbox = (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 Pathclass BaseDriver():win_width = Nonewin_height = Nonewin_url = Noneimage_path = Nonetemp_path = Noneimage_name = Noneshot_driver = Noneshot_callback = Nonewin_x = 0win_y = 0def setWindowPosition(self, x, y):self.win_x = xself.win_y = yreturn selfdef setWindowSize(self, width, height):print('BaseDriver->setWindowSize')self.win_width = widthself.win_height = heightreturn selfdef setSavePath(self, save_path):print('BaseDriver->setSavePath')self.image_path = save_pathreturn selfdef setTempPath(self, temp_path):self.temp_path = temp_pathreturn selfdef url(self, url:str):print('BaseDriver->url')self.win_url = urlreturn selfdef filename(self, filename):print('BaseDriver->filename')self.image_name = filenamereturn selfdef driver(self, driver):print('BaseDriver->driver')self.shot_driver = driverreturn selfdef shotCallback(self, callback):print('BaseDriver->shotCallback')self.shot_callback = callbackreturn selfdef checkShotCallback(self, file=None, error=None):if (self.shot_callback):self.shot_callback({'file': file,'error': error})return selfdef 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_pathdef 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_pathdef 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 tracebackclass Screenshot():pModel_QT5 = 1pModel_Selenium = 2sDriver_Phantomjs = 1sDriver_Chrome = 2win_url = ''win_width = Nonewin_height = Nonesave_path = Nonetemp_path = Noneshot_pModel = pModel_Seleniumshot_driver = sDriver_Phantomjsshot_callback = Nonewin_x = 0win_y = 0def __init__(self):print('ScreenShot->__init__')passdef setWindowPosition(self, x, y):self.win_x = xself.win_y = yreturn selfdef url(self, url):print('Screenshot->url')self.win_url = urlreturn selfdef pModel(self, model):print('Screenshot->pmodel')self.shot_pModel = modelreturn selfdef driver(self, driver):print('Screenshot->driver')self.shot_driver = driverreturn  selfdef setWindowSize(self, width , height):print('Screenshot->setWindowSize')self.win_width = widthself.win_height = heightreturn selfdef savePath(self, path):print('Screenshot->savePath')self.save_path = Path(path)if(not self.save_path.exists()):self.save_path.mkdir(parents=True)return selfdef selenium(self):print('Screenshot->selenium')return selenium.Selenium()def pyqt5(self):print('Screenshot->pyqt5')obj = MainWindow.MainWindow()return objdef shotCallback(self, callback):print('Screenshot->shotCallback')self.shot_callback = callbackreturn selfdef getDriver(self):print('Screenshot->getDriver')result = switch(self.shot_pModel, {self.pModel_QT5: self.pyqt5,self.pModel_Selenium: self.selenium,'default': self.selenium})return resultdef 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_pathdef getTempPath(self):print('Screenshot->getTempPath')path = Path(__file__).parent.joinpath('image/temp')if(not path.exists()):path.mkdir(parents=True)return pathdef 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

python实现网页截图功能——学习篇(01)相关推荐

  1. Python实现网页截图,附带完整代码

    Python实现网页截图,附带完整代码 在现代化的互联网时代,我们经常需要对网页进行截图以便于保存.共享以及其他种种用途.Python是一种功能强大的编程语言,可以帮助我们轻松地实现网页截图功能.本文 ...

  2. axure交互页面设计【学习篇01】

    axure学习记录一.2020.0305 未来会在这个专题下不定期更一些关于axure学习日常,小白入手,希望大家能够一起学习进步吧~ 今天这期教程是跟着b站 up主av40374556 学习的,附上 ...

  3. python调用微信截图功能

    本文介绍python调用微信截图功能实现:监听键盘按键,触发截图功能 一.技术原理 通过dos方式调用PrScrn.dll来实现截图功能 通过监听键盘按键触发截图 二.安装库 venv\Scripts ...

  4. Python实现网页截图

    方案说明 功能要求:实现网页加载后将页面截取成长图片 涉及模块:PyQT5 PIL 逻辑说明: 1:完成窗口设置,利用PyQT5 QWebEngineView加载网页地址,待网页加载完成后,调用che ...

  5. html网页截图功能支持svg图片保存

    根据自己的需求选取对应代码片段,可以节省50%的时间. 现在用到最多的页面截取插件就是html2canvas.将页面转化为canvas进行保存 但是为了兼容支持svg页面的截图,会先将svg页面转化成 ...

  6. C#实现网页截图功能

    //需要添加System.Drawing及System.Windows.Forms引用 using System; using System.Drawing; using System.Drawing ...

  7. python谷歌网页爬虫_python爬虫入门01:教你在 Chrome 浏览器轻松抓包

    通过 python爬虫入门:什么是爬虫,怎么玩爬虫? 我们知道了什么是爬虫 也知道了爬虫的具体流程 那么在我们要对某个网站进行爬取的时候 要对其数据进行分析 就要知道应该怎么请求 就要知道获取的数据是 ...

  8. python︱HTML网页解析BeautifulSoup学习笔记

    一.载入html页面信息 一种是网站在线的网页.一种是下载下来的静态网页. 1.在线网页 参考<python用BeautifulSoup库简单爬虫入门+案例(爬取妹子图)>中的载入内容: ...

  9. python界面开发webview_Python+Appium学习篇之WebView处理

    原博文 2018-11-17 21:26 − 本文转自:https://www.cnblogs.com/luobobobo/p/9344641.html 1.认识WebView 实例说明: 当你打开百 ...

  10. pythonchallenge之C++学习篇-01

    字符处理时每个语言都具备的一种功能,其中还有一些语言因此出名,比如perl,shell,还有一些函数式的编程语言 C语言中的字符串与数组和指针联系的比较紧密,因此可以这样生命字符串*p="h ...

最新文章

  1. open***在Windows客户端权限那些事
  2. Mac环境下配置Java开发环境(jdk+maven+tomcat+idea)
  3. 麦当劳java排班_学习肯德基排班管理系统
  4. python list_Python中的基本list操作
  5. can not open include file afxwin.h :no such header fileor directory in vs 2015 c++
  6. 数据结构----数组与广义表专题
  7. 实时音频抗弱网技术揭秘
  8. BootStrap 杂记
  9. GC和JVM调优实战
  10. 深入理解Spark 2.1 Core (十三):sparkEnv类源码分析
  11. 前端学习(972):swiper插件使用 参数更改
  12. ‘cnpm‘ 不是内部或外部命令,也不是可运行的程序
  13. MongoDB数据库CXX Driver编译
  14. STM32CubeMX GPIO的使用
  15. mysq 正序查询并且0排在最后
  16. oracle 联表求和不重复_糊涂了10年,这个Excel公式到底是怎么不重复计数的?
  17. CentOS桥接网卡配置
  18. 高洛峰细说php百度贴吧_高洛峰细说PHP视频教程推荐
  19. 基于java五子棋游戏设计与实现
  20. 杂记之BOOTLOAD和U-BOOT

热门文章

  1. 文件系统 - 文件类型 - 二进制/文本类型
  2. 限抗时代,化药里卖得最好的还是头孢!
  3. 工业相机和镜头参数简析
  4. Arduino UNO步进电机控制
  5. TCP/IP协议讲解
  6. 用c#查询各快递物流信息
  7. Could not resolve subtype of [simple type, class org.apereo.cas.services.Reg...
  8. python list倒序_Python 面试:这9个问题你一定要掌握!
  9. 微信状态栏隐藏 HTML,完美解决微信video视频隐藏控件和内联播放问题
  10. python的自省与反射机制