2016-08-06 52 views
0

我希望以下代碼在網頁加載過程中獲取以http://down.51en.com:88開頭的請求url,然後使用url的響應對象執行其他處理。 在我的程序中,一旦給targetUrl分配了一個值,我希望函數targetUrlGetter(url)將其返回給調用者,但問題是QApplication::exec()進入主事件循環,因此無法在執行exec之後的targetUrlGetter()函數結束時執行代碼()調用,因此函數不能返回,我試着用qApp.quit()interceptRequest(self, info)爲了告訴程序退出,所以targetUrlGetter(url)可以返回,但是函數仍然不能返回,程序甚至在退出時崩潰(在Win7 32bit上測試過) ,那麼我怎樣才能將targetUrl返回給調用者程序呢?在函數或類中使用QApplication :: exec()

這裏的困難是如何在不發生崩潰的情況下退出Qt事件循環並將請求url返回給調用者。

import sys 

from PyQt5.QtWidgets import * 
from PyQt5.QtWebEngineWidgets import * 
from PyQt5.QtWebEngineCore import * 
from PyQt5.QtCore import * 


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.page = parent 

    def interceptRequest(self, info): 
     if info.requestUrl().toString().startswith('http://down.51en.com:88'): 
      self.targetUrl = info.requestUrl().toString() 
      print('----------------------------------------------', self.targetUrl) 
      qApp.quit() 

      # self.page.load(QUrl('')) 


def targetUrlGetter(url=None): 
    app = QApplication(sys.argv) 
    page = QWebEnginePage() 
    globalSettings = page.settings().globalSettings() 
    globalSettings.setAttribute(
     QWebEngineSettings.PluginsEnabled, True) 
    globalSettings.setAttribute(
     QWebEngineSettings.AutoLoadImages, False) 
    profile = page.profile() 
    webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page) 
    profile.setRequestInterceptor(webEngineUrlRequestInterceptor) 
    page.load(QUrl(url)) 
    # view = QWebEngineView() 
    # view.setPage(page) 
    # view.show() 
    app.exec_() 
    return webEngineUrlRequestInterceptor.targetUrl 


url = "http://www.51en.com/news/sci/everything-there-is-20160513.html" 
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html" 
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html" 
targetUrl = targetUrlGetter(url) 
print(targetUrl) 
+0

我不能重現這一點。腳本運行時沒有錯誤,並按預期打印/返回請求的URL。我不明白爲什麼'exec()'應該「掛起」。你確定沒有網絡問題嗎? – ekhumoro

+0

@ekhumoro對不起,我可憐的英語,再次看到更新的帖子!如果看不到退出崩潰,請在Windows上多次測試代碼 – iMath

+0

我無法在Windows上測試。該腳本在Linux上正常工作。您需要進行一些基本的調試以查看腳本失敗的位置。網頁加載是否正確?使用[loadFinished signal](http://doc.qt.io/qt-5/qwebenginepage.html#loadFinished)進行檢查。 'interceptRequest'是否被調用,如果是,'print(repr(info.requestUrl()。toString()))'的輸出是什麼? if語句是否評估爲「真」? – ekhumoro

回答

-1

你應該總是在程序的開頭初始化QApplication,並始終調用QApplication::exec功能在節目的結尾。

另一件事是QWebEngineUrlRequestInterceptor.interceptRequest是一個異步調用的回調函數。由於info.requestUrl().toString()在回調函數中被調用,所以沒有辦法return它的結果是同步的。

import sys 

from PyQt5.QtWidgets import * 
from PyQt5.QtWebEngineWidgets import * 
from PyQt5.QtWebEngineCore import * 
from PyQt5.QtCore import * 


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.page = parent 

    def interceptRequest(self, info): 
     if info.requestUrl().toString().startswith('http://down.51en.com:88'): 
      self.targetUrl = info.requestUrl().toString() 
      print('----------------------------------------------', self.targetUrl) 
      # Don't do thatDo you really want to exit the whole program? 
      # qApp.quit() 

      # Do something here, rather than return it. 
      # It must be run asynchronously 

      # self.page.load(QUrl('')) 


def targetUrlGetter(url=None): 
    page = QWebEnginePage() 
    globalSettings = page.settings().globalSettings() 
    globalSettings.setAttribute(
     QWebEngineSettings.PluginsEnabled, True) 
    globalSettings.setAttribute(
     QWebEngineSettings.AutoLoadImages, False) 
    profile = page.profile() 
    webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page) 
    profile.setRequestInterceptor(webEngineUrlRequestInterceptor) 
    page.load(QUrl(url)) 
    # view = QWebEngineView() 
    # view.setPage(page) 
    # view.show() 

    # Don't return this. It cannot be called synchronously. It must be called asynchronously. 
    # return webEngineUrlRequestInterceptor.targetUrl 

app = QApplication(sys.argv) # always initialize QApplication at the beginning of the program 
url = "http://www.51en.com/news/sci/everything-there-is-20160513.html" 
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html" 
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html" 
targetUrl = targetUrlGetter(url) 
print(targetUrl) 
app.exec_() # always call the QApplication::exec at the end of the program 
+0

這是一個錯誤的答案 – iMath

相關問題