Python实现网页截图
生活随笔
收集整理的這篇文章主要介紹了
Python实现网页截图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
方案說明
功能要求:實現網頁加載后將頁面截取成長圖片
涉及模塊: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 = 0self.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, 1370desktop = 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;
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' 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 = 1self.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 -= 1def run_js(self):script = """var scroll = function (dHeight) {var t = document.documentElement.scrollTopvar h = document.documentElement.scrollHeightdHeight = dHeight || 0var current = t + dHeightif (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在每次截圖完成后將圖片保存,并將圖片對象由圖片合并根據保存到列表中。
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' 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 = pageself.over_flow_size = over_flow_sizeself.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 = 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, ):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(self.save_path)print('截圖成功:', self.save_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(self.save_path)print('截圖成功:', self.save_path)def reedit_image(self, path):obj = Image.open(path)width, height = obj.sizeleft, top, right, bottom = 0, height - self.over_flow_size, width, heightbox = (left, top, right, bottom)region = obj.crop(box)return region截圖功能完整代碼
#!/usr/bin/env python # -*- coding:UTF-8 -*- #遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 #尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書!import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtWebEngineWidgets import * from PIL import Image from pathlib import Pathclass ScreenShotMerge():def __init__(self, page, over_flow_size):self.im_list = []self.page = pageself.over_flow_size = over_flow_sizeself.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 = 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, ):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(self.save_path)print('截圖成功:', self.save_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(self.save_path)print('截圖成功:', self.save_path)def reedit_image(self, path):obj = Image.open(path)width, height = obj.sizeleft, top, right, bottom = 0, height - self.over_flow_size, width, heightbox = (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 = 0self.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, 1370desktop = 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 = 1self.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 -= 1def run_js(self):script = """var scroll = function (dHeight) {var t = document.documentElement.scrollTopvar h = document.documentElement.scrollHeightdHeight = dHeight || 0var current = t + dHeightif (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实现网页截图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python实现图片压缩
- 下一篇: 利用Python编辑一个发送邮件的脚本