python - Saving a website screenshot with pyqt6QtWebEngineView is always empty - Stack Overflow

admin2025-05-02  0

I'm trying to save a screenshot of a website with QtWebEngineView, but the resulting image always ends up being empty.


import sys
import time
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView

class Screenshot(QWebEngineView):
    def __init__(self):
        self.app = QApplication(sys.argv)
        QWebEngineView.__init__(self)
        self._loaded = False
        self.loadFinished.connect(self._loadFinished)

    def capture(self, url, output_file):
        self.resize(QSize(1024, 768))
        self.load(QUrl(url))
        self.wait_load()

        image = QImage(self.size(), QImage.Format.Format_ARGB32)
        painter = QPainter(image)
        self.render(painter)
        painter.end()
        image.save(output_file)

    def wait_load(self, delay=0):
        # process app events until page loaded
        while not self._loaded:
            self.app.processEvents()
            time.sleep(delay)
        self._loaded = False

    def _loadFinished(self, result):
        self._loaded = True

s = Screenshot()
s.capture(";, "screenshot.png")

I've tried variations of the code where the QTWebEngineView is rendered in an application window and that part works. The wait_load also ensures the website is loaded before proceeding to paint. Yet somehow the rendered image is always a full white png instead of the website.

Edit: Voting to reopen because the solution in the "duplicate" does not seem to resolve this case.

I'm trying to save a screenshot of a website with QtWebEngineView, but the resulting image always ends up being empty.


import sys
import time
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView

class Screenshot(QWebEngineView):
    def __init__(self):
        self.app = QApplication(sys.argv)
        QWebEngineView.__init__(self)
        self._loaded = False
        self.loadFinished.connect(self._loadFinished)

    def capture(self, url, output_file):
        self.resize(QSize(1024, 768))
        self.load(QUrl(url))
        self.wait_load()

        image = QImage(self.size(), QImage.Format.Format_ARGB32)
        painter = QPainter(image)
        self.render(painter)
        painter.end()
        image.save(output_file)

    def wait_load(self, delay=0):
        # process app events until page loaded
        while not self._loaded:
            self.app.processEvents()
            time.sleep(delay)
        self._loaded = False

    def _loadFinished(self, result):
        self._loaded = True

s = Screenshot()
s.capture("https://www.google.com", "screenshot.png")

I've tried variations of the code where the QTWebEngineView is rendered in an application window and that part works. The wait_load also ensures the website is loaded before proceeding to paint. Yet somehow the rendered image is always a full white png instead of the website.

Edit: Voting to reopen because the solution in the "duplicate" does not seem to resolve this case.

Share Improve this question edited Jan 2 at 15:48 kontur asked Jan 2 at 14:13 konturkontur 5,2542 gold badges39 silver badges68 bronze badges 2
  • Try adding self.setAttribute(Qt.WidgetAttribute.WA_DontShowOnScreen) right after the __init__. Yet, I'm not that sure it would work. The problem is that the view is normally shown with an embedded OpenGL widget, which is the reason for which it doesn't capture anything. – musicamante Commented Jan 2 at 15:05
  • @musicamante unfortunately still a white png. – kontur Commented Jan 2 at 15:46
Add a comment  | 

1 Answer 1

Reset to default 2

The problem is caused by the QWebengineView not being rendered because the show() method is not called. As indicated in the other posts you should also use Qt.WidgetAttribute.WA_DontShowOnScreen. Here is a version that avoids using time.sleep and QXApplication.processEvents.

import sys
from PyQt6.QtCore import Qt, QEventLoop, QSize, QUrl
from PyQt6.QtGui import QImage, QPainter
from PyQt6.QtWidgets import QApplication
from PyQt6.QtWebEngineWidgets import QWebEngineView


class Screenshot(QWebEngineView):
    def __init__(self):
        self.app = QApplication(sys.argv)
        QWebEngineView.__init__(self)
        self.setAttribute(Qt.WidgetAttribute.WA_DontShowOnScreen)
        self.show()
        self._output_file = ""
        self._loop = QEventLoop()
        self.loadFinished.connect(self._loop.quit)

    def capture(self, url, output_file):
        self._output_file = output_file
        self.resize(QSize(1024, 768))
        self.load(QUrl(url))
        self.wait_load()

    def wait_load(self):
        self._loop.exec()
        image = QImage(self.size(), QImage.Format.Format_ARGB32)
        painter = QPainter(image)
        self.render(painter)
        painter.end()
        image.save(self._output_file)


s = Screenshot()
for i in range(10):
    s.capture("https://www.google.com", f"screenshot{i}.png")
转载请注明原文地址:http://www.anycun.com/QandA/1746115299a91881.html