0

I am using the below code to take screenshot from a webpage. But the problem is I am getting blank screenshot for certain websites. Obviously the reason is the page size is not fitting. Can some one please help me to fix this code so that it works for all webpages.

import sys
import time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *

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

    def capture(self, url, output_file):
        self.load(QUrl(url))
        self.wait_load()
        # set to webpage size
        frame = self.page().mainFrame()
        self.page().setViewportSize(frame.contentsSize())
        # render image
        image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        print ('saving', output_file)
        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://docs.python.org/2/library/', 'website3.png')

I have tried to modify like below from a similar thread: PyQt: QImage() returns a 'Null'-Image. I have made a change according to the post but cant make it work.

import sys
import time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *

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

    def capture(self, url, output_file):
        self.load(QUrl(url))
        self.wait_load()
        # set to webpage size
        frame = self.page().mainFrame()
        self.page().setViewportSize(frame.contentsSize())
        # render image
        image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        print ('saving', output_file)
        image.save(output_file)

    def wait_load(self, delay=0):
        # process app events until page loaded
        frame = self.page().mainFrame()
        if  frame.contentsSize().width() == 0 or frame.contentsSize().height() == 0:
           print ('ContentsSize = (w: {}, h: {})'.format(frame.contentsSize().width(), frame.contentsSize().height()))
           count = 0 # used so we're not starting an infinite loop
           while (frame.contentsSize().width() == 0 or frame.contentsSize().height() == 0) and count < 5:
              count += 1
           self.app.processEvents()
           time.sleep(1)
           self._loaded = False

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

s = Screenshot()
s.capture('https://stackoverflow.com/','website4.png')
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Andy
  • 405
  • 1
  • 5
  • 16

0 Answers0