【问题标题】:pyqt4: Loop main Render class?pyqt4:循环主渲染类?
【发布时间】:2016-01-05 03:53:20
【问题描述】:

我有一个 PyQt4 类,可以下载我用于报废的网页。

当我在实例化时将 url 列表传递给 Render 类时,它可以正常工作(单次调用),但是当我尝试使用多个 url 列表循环 [r = Render(url, cb=scrape)] 时,之后第一个循环,执行停止或挂起,没有抛出任何错误。

我想单独循环这个类,因为 urls 列表属于不同的类别,并且必须单独存储提取的内容。

我也开始知道只能启动一个应用程序,如果是这种情况如何退出应用程序而不退出它。这样新的 url 列表可以被同一个应用程序使用

我被这个问题困扰了一段时间。提前致谢

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

class Render(QWebPage):  
  def __init__(self, urls, cb):
    self.app = QApplication(sys.argv)  
    QWebPage.__init__(self)  
    self.loadFinished.connect(self._loadFinished)  
    self.urls = urls  
    self.cb = cb
    self.crawl()  
    self.app.exec_()  

  def crawl(self):  
    if self.urls:  
      url = self.urls.pop(0)  
      print 'Downloading', url  
      self.mainFrame().load(QUrl(url))  
    else:  
      self.app.quit()  

  def _loadFinished(self, result):  
    frame = self.mainFrame()  
    url = str(frame.url().toString())  
    html = frame.toHtml()  
    self.cb(url, html)
    self.crawl()  

def scrape(url, html):
    pass # have scraping code here

url1 = ['http://webscraping.com', 'http://webscraping.com/blog'] 
url2 = ['http://webscraping.com', 'http://webscraping.com/blog']
urls =[]
urls.append(url1)
urls.append(url2)

for url in urls:
    r = Render(url, cb=scrape)

【问题讨论】:

  • 为什么要在Render 里面创建一个QApplication ?为什么不只有一次,在课外?这可能是问题所在。
  • 即使我们在 render 之外创建了一个应用,也需要调用 app.quit() 来退出一个 url 列表的处理循环。只有当循环停止时,才能传递下一个 url 列表。但问题是一旦 app.quit() 被调用,它就会终止应用程序并且无法创建新的应用程序。那么,我想知道有没有办法在不退出应用程序的情况下退出循环?
  • 我不熟悉QWepPage,但在我看来你可以简单地删除else: self.app.quit()。如果self.urls 为False,则不调用load,也不发出loadFinished,因此循环退出。
  • @Mel 如果 app.quit 被移除,那么执行将永远不会返回到主循环

标签: python python-2.7 events pyqt4


【解决方案1】:

问题是您只能实例化一个 QApplication 对象。这是避免这种情况的更新版本,然后仅在下载 URL 时运行 Qt 的执行循环:

import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QUrl
from PyQt4.QtWebKit import QWebPage

class Render(QWebPage):
  def __init__(self, cb):
    self.app = QApplication(sys.argv)
    QWebPage.__init__(self)
    self.loadFinished.connect(self._loadFinished)
    self.cb = cb

  def crawl(self, url):
    print 'Downloading', url
    self.mainFrame().load(QUrl(url))
    self.app.exec_()

  def _loadFinished(self, result):
    frame = self.mainFrame()
    url = str(frame.url().toString())
    html = frame.toHtml()
    self.cb(url, html)
    self.app.quit()


def scrape(url, html):
  pass # add scraping code here
  print len(html)


r = Render(cb=scrape)
urls = ['http://webscraping.com', 'http://webscraping.com/blog']
for url in urls:
    r.crawl(url)

【讨论】:

  • 这真的很棒@hoju。但是,我似乎遇到了不同网址的问题。如果我将 'http://themonkeycage.org/https://www.washingtonpost.com/news/volokh-conspiracy/ 添加到 URL 列表中,该过程似乎挂起。有超时问题吗?很高兴发布另一个问题...
【解决方案2】:

不幸的是,@hoju 的回答对我不起作用。

这对我有用(基本上是设置一个计时器来检查加载是否完成)。

import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QUrl, QTimer
from PyQt4.QtWebKit import QWebPage


class Render(QWebPage):
    def __init__(self, url):
        QWebPage.__init__(self)
        self.frame = None
        self.mainFrame().loadFinished.connect(self._loadFinished)
        self.mainFrame().load(QUrl(url))

    def _loadFinished(self, result):
        self.frame = self.mainFrame()

def go_again():
    global r, timer, urls
    if(len(urls)>0):
        print("loading",urls[0])
        r = Render(urls.pop())
        timer.start(1000)
    else:
        print("finished")
        sys.exit(app.exec_())

def check_done():
    global r, timer
    if r.frame is not None:
        timer.stop()
        html_result = r.frame.toHtml()
        #do something with html
        print("loaded")
        go_again()

app = QApplication(sys.argv)
urls = ['http://stackoverflow.com/questions/34603886/pyqt4-loop-main-render-class','http://stackoverflow.com/questions/34603886/pyqt4-loop-main-render-class']

timer = QTimer()
timer.timeout.connect(check_done)
#check every second
go_again()
sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多