使用pyside拍摄iFrame的屏幕截图

时间:2013-01-07 12:02:48

标签: python qt python-3.x pyqt pyside

我在浏览Google翻译页面时遇到问题。下面的脚本工作正常(截图)没有谷歌翻译:

class Render(QWebPage):
    def __init__(self, url):
        self.web_page = QWebPage()
        self.finished = False
        s = self.web_page.settings()
        s.setAttribute(QWebSettings.JavascriptCanOpenWindows, False)
        s.setAttribute(QWebSettings.PluginsEnabled, True)
        self.web_page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.web_page.loadFinished.connect(self._loadFinished)  
        self.web_page.mainFrame().load(QUrl(url))

    def _loadFinished(self, result):
        frame = self.web_page.mainFrame()
        size = frame.contentsSize()
        size.setWidth(1000)
        self.web_page.setViewportSize(size)
        image = QImage(self.web_page.viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        self.filepath="screenshot_name.jpg"
        image.save(self.filepath)
        self.finished = True

def run(url):
    app=QApplication.instance()
    if not app:
        app = QApplication(sys.argv)
    r = Render(url)
    while not r.finished:
        app.processEvents()
        time.sleep(0.01)
    return r.filepath

news_url="http://arabic-media.com/arabicnews.htm"
news_url_google_translate = "http://translate.google.com/translate?hl=en&sl=auto&tl=en&u="+news_url
run(news_url_google_translate)

但我需要截取翻译页面的截图。 Google翻译的页面会创建iframe。所以我使用以下内容来截取内部框架(name = c):

frame = self.web_page.mainFrame().childFrames()[0]

不幸的是,我的剧本仍在拍黑色截图。

2 个答案:

答案 0 :(得分:1)

查看此示例是否适合您。网络管理器的finished信号连接到一个插槽,用于检查已完成下载的网址,并在其中找到urlRequest时触发屏幕截图:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork

urlTranslate = "http://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http://arabic-media.com/arabicnews.htm"
urlRequest   = "http://www.google.com/cse/intl/ar/images/google_custom_search_watermark.gif"

class myWindow(QtWebKit.QWebView):
    def __init__(self, parent=None):
        super(myWindow, self).__init__(parent)

        self.page().mainFrame().setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
        self.page().mainFrame().setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)

        self.page().networkAccessManager().finished.connect(self.on_networkAccessManager_loadFinished)

        self.load(QtCore.QUrl(urlTranslate))

    @QtCore.pyqtSlot(QtNetwork.QNetworkReply)
    def on_networkAccessManager_loadFinished(self, reply):
        if urlRequest in reply.url().toString():
            self.takeScreenshot()

    def takeScreenshot(self):
        fileName = self.title() + ".png"

        self.page().setViewportSize(QtCore.QSize(1000, 2000))

        image   = QtGui.QImage(self.page().viewportSize(), QtGui.QImage.Format_ARGB32)
        painter = QtGui.QPainter(image)

        self.page().mainFrame().render(painter)
        painter.end()

        if not image.isNull():
            image.save(fileName)
            print "Succesfully saved '{0}'".format(fileName)

        else:
            print "Failed to save '{0}'".format(fileName)

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('myWindow')

    main = myWindow()
    main.show()

    sys.exit(app.exec_())

image

答案 1 :(得分:0)

我已使用下面的代码修复了整页加载问题。现在这个代码将在30秒后停止,它将截取屏幕截图。

    self.web_page.networkAccessManager().finished.connect(self.on_networkAccessManager_loadFinished)
    self._error = None

    request = QNetworkRequest()
    request.setUrl(QUrl(url))

    self.timeout_timer = QTimer()
    self.timeout_timer.timeout.connect(self._request_timed_out)

    self.timeout_timer.start(30 * 1000)  #30 seconds
    self.web_page.mainFrame().load(request)

def _request_timed_out(self):
    self._error = 'Custom request timeout value exceeded.'
    print self._error
    self.timeout_timer.stop()
    self.web_page.killTimer(0)
    self.web_page.loadFinished.emit(False)
    self.takeScreenshot()