2014-12-22 10 views
2

PySide의 QtWebKit 모듈을 사용하여 웹 페이지를로드하려고합니다. 그렇지 않은 아아웹 페이지로드

from PySide import QtCore 
from PySide import QtGui 
from PySide import QtWebKit 

# Needed if we want to display the webpage in a widget. 
app = QtGui.QApplication([]) 

view = QtWebKit.QWebView(None) 
view.setUrl(QtCore.QUrl("http://www.google.com/")) 
frame = view.page().mainFrame() 
print(frame.toHtml()) 

그러나 :; 문서 (Elements of QWebViewQWebFrame::toHtml())에 따르면, 다음 스크립트는 구글 검색 페이지의 HTML을 인쇄해야합니다.

뷰 충분한 데이터가 표시 도착 때까지 동일하게 유지 :

<html><head></head><body></body></html>

그래서 나는 setUrl documentation에 대해 자세히 살펴했다 : 인쇄되는 모든 널 응답의 방법의 동등 새로운 URL.

이렇게하면 서버에서 응답을 받기 전에 너무 빨리 toHtml() 메서드를 호출하고 있다고 생각했습니다. 전혀 차이를하지

import time 

class View(QtWebKit.QWebView): 
    def __init__(self, *args, **kwargs): 
     super(View, self).__init__(*args, **kwargs) 
     self.completed = True 
     self.loadFinished.connect(self.setCompleted) 

    def setCompleted(self): 
     self.completed = True 

    def setUrl(self, url): 
     self.completed = False 
     super(View, self).setUrl(url) 
     while not self.completed: 
      time.sleep(0.2) 

view = View(None) 
view.setUrl(QtCore.QUrl("http://www.google.com/")) 
frame = view.page().mainFrame() 
print(frame.toHtml()) 

: 그래서 loadFinished 신호가 트리거 될 때까지 블록의 setUrl 방법을 재정의하는 클래스를 썼다. 내가 여기서 무엇을 놓치고 있니?

편집 : 단지 페이지의 HTML을 얻는 것이 나의 최종 게임이 아닙니다. 이것은 내가 예상했던대로 작동하지 않는 코드의 간단한 예입니다.

답변

3

my other answer에서 복사 app.processEvents와 교체 time.sleep을()() 제안에 대한 올레에 대한 신용 :

from PySide.QtCore import QObject, QUrl, Slot 
from PySide.QtGui import QApplication 
from PySide.QtWebKit import QWebPage, QWebSettings 

qapp = QApplication([]) 

def load_source(url): 
    page = QWebPage() 
    page.settings().setAttribute(QWebSettings.AutoLoadImages, False) 
    page.mainFrame().setUrl(QUrl(url)) 

    class State(QObject): 
     src = None 
     finished = False 

     @Slot() 
     def loaded(self, success=True): 
      self.finished = True 
      if self.src is None: 
       self.src = page.mainFrame().toHtml() 
    state = State() 

    # Optional; reacts to DOM ready, which happens before a full load 
    def js(): 
     page.mainFrame().addToJavaScriptWindowObject('qstate$', state) 
     page.mainFrame().evaluateJavaScript(''' 
      document.addEventListener('DOMContentLoaded', qstate$.loaded); 
     ''') 
    page.mainFrame().javaScriptWindowObjectCleared.connect(js) 

    page.mainFrame().loadFinished.connect(state.loaded) 

    while not state.finished: 
     qapp.processEvents() 

    return state.src 

load_source URL에서 데이터를 다운로드하고 웹킷에 의해 수정 후 HTML을 반환합니다. Qt의 이벤트 루프를 비동기 이벤트로 래핑하고 차단 기능입니다.

하지만 당신은 정말로 당신이하고있는 일을 생각해야합니다. 실제로 엔진을 호출하고 수정 된 HTML을 가져올 필요가 있습니까? 일부 웹 페이지의 HTML 만 다운로드하려는 경우이를 수행 할 수있는 훨씬 간단한 방법이 있습니다.

이제 답안의 코드 문제는 Qt가 아무 것도하지 못하도록한다는 것입니다. 백그라운드에서 실행되는 마법 같은 일은 없습니다. Qt는 이벤트 루프를 기반으로하므로 루프에 들어가게하지 마십시오. 대개 을 호출하거나 내 코드에 표시된대로 processEvents으로 해결할 수 있습니다. time.sleep(0.2)app.processEvents()으로 바꿀 수 있으며 효과가있을 수 있습니다.

+0

app.ProcessEvents()는 내가 원했던 것입니다. 감사! – nullstellensatz