我正在尝试使用PyQT5 QWebEngineView进行网页抓取。这是我从StackOverflow的另一个响应中获得的代码:
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEngineView
import sys
def render(url):
class Render(QWebEngineView):
def __init__(self, t_url):
self.html = None
self.app = QApplication(sys.argv)
QWebEngineView.__init__(self)
self.loadFinished.connect(self._loadfinished)
self.load(QUrl(t_url))
while self.html is None:
self.app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
self.app.quit()
def _callable(self, data):
self.html = data
def _loadfinished(self, result):
self.page().toHtml(self._callable)
return Render(url).html
然后,如果我把这一行:
print(render('http://quotes.toscrape.com/random'))
它按预期工作。但是,如果我在上面添加第二行,它显示为:
print(render('http://quotes.toscrape.com/random'))
print(render('http://quotes.toscrape.com/tableful/'))
正确打印出第一个渲染后,出现错误“处理以退出代码-1073741819(0xC0000005)完成”。
我将错误范围缩小到self.load(QUrl(t_url))
答案 0 :(得分:1)
您要多次初始化QApplication。全局仅应存在一次实例。如果您需要获取当前实例并且没有该实例的句柄,则可以使用QApplication.instance()
。 QApplication.quit()
的意思是在sys.exit
之前被调用,实际上,您几乎切勿在没有另一个的情况下使用一个。
简而言之,您要告诉Qt您正在退出该应用程序,然后尝试运行更多Qt代码。这很简单,但是...
您可以做三件事之一:
将应用程序存储在全局变量中,然后从那里引用它:
APP = QApplication(sys.argv)
# ... Many lines ellipsed
class SomeClass(QWidget):
def some_method(self):
APP.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
将app
作为该类的句柄。
def render(app, url):
...
创建一个全局实例,并使用QApplication.instance()
。
APP = QApplication(sys.argv)
# ... Many lines ellipsed
class SomeClass(QWidget):
def some_method(self):
app = QApplication.instance()
app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
做最适合您的事情。