Search code examples
pythonpyqt4qtwebkit

Set Parameters of Screenshot taken by Python


I have used the following code to take the screen shot of the web page. From the code I understand that first the complete page is loaded in the frame and then the frame is rendered in painter. The problem I am facing is that some web pages might be very very lengthy in terms of content, but I would just want the screen shot of the first page of website. Is there any way I can handle that?

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)

I have tried to set Preferred size of frame with the help of QSize object, but it wont help either. Or alternative, is there any way I can crop image? Any help is highly appreciated, Thanks.


Solution

  • There is no such thing as "the first page". It's entirely up to the application to decide how to divide up the content.

    At the moment, your script explicitly sets the first division to be the entire contents of the page. To avoid that, you should simply decide how much of the content you want to capture, and then resize the viewport as appropriate.

    The demo script below uses QPrinter to calculate an A4 page size:

    usage: capture.py url > webpage.png
    
    from PyQt4 import QtCore, QtGui, QtWebKit
    
    class WebPage(QtWebKit.QWebPage):
        def __init__(self):
            QtWebKit.QWebPage.__init__(self)
            self.mainFrame().setScrollBarPolicy(
                QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
            self.mainFrame().setScrollBarPolicy(
                QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
            self.mainFrame().loadFinished.connect(self.handleLoadFinished)
            printer = QtGui.QPrinter()
            printer.setPaperSize(QtGui.QPrinter.A4)
            self.setViewportSize(printer.paperSize(
                QtGui.QPrinter.DevicePixel).toSize())
    
        def capture(self, url):
            self._url = QtCore.QUrl(url)
            QtCore.QTimer.singleShot(0, self.handleLoad)
    
        def handleLoad(self):
            self.mainFrame().load(self._url)
    
        def handleLoadFinished(self):
            image = QtGui.QImage(self.viewportSize(),
                                 QtGui.QImage.Format_ARGB32)
            painter = QtGui.QPainter(image)
            self.mainFrame().render(painter)
            painter.end()
            output = QtCore.QFile()
            output.open(1, QtCore.QIODevice.WriteOnly)
            image.save(output, 'PNG')
            sys.exit(0)
    
    if __name__ == '__main__':
    
        import sys, signal
        app = QtGui.QApplication(sys.argv)
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        page = WebPage()
        page.capture(sys.argv[1])
        sys.exit(app.exec_())