侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python实现网页截图(PyQT5)过程解析

Python  /  管理员 发布于 7年前   327

方案说明

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

涉及模块: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_())

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    python利用itertools生成密码字典并多线程撞库破解rar密码
    下一条:
    python实现知乎高颜值图片爬取
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客