Python Can';用PyQt5多次刮网
我正在尝试使用PyQT5 QWebEngineView进行web刮取。下面是我从StackOverflow的另一个响应中得到的代码:Python Can';用PyQt5多次刮网,python,python-3.x,web-scraping,pyqt,pyqt5,Python,Python 3.x,Web Scraping,Pyqt,Pyqt5,我正在尝试使用PyQT5 QWebEngineView进行web刮取。下面是我从StackOverflow的另一个响应中得到的代码: from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QUrl, QEventLoop from PyQt5.QtWebEngineWidgets import QWebEngineView import sys def render(url): class Render(QW
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))
您多次初始化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)