如何在QtPy5中将CookieStore刷新到磁盘



我的目标是将QWebEngineViewcookie保存到磁盘上,这样,如果打开该小部件的应用程序关闭,则始终在应用程序退出之前将cookie可靠地保存到磁盘。这样,当应用程序再次执行时,它将从上一次运行的cookie值开始。

使用下面的代码,将新的cookie值实际写入磁盘几乎需要整整一分钟的时间。如果应用程序在此点之前关闭,则新的cookie值将永远不会写入磁盘。

以下是一个示例程序,该程序使用PyQt5和保存到磁盘的带有cookie的QWebEngineView在Windows 10中的Python3中打开网页:

from pathlib import Path
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
import sys
site = 'https://stackoverflow.com/search?q=pyqt5+forcepersistentcookies'

class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
QMainWindow.__init__(self, *args, **kwargs)
self.webview = QWebEngineView()
profile = QWebEngineProfile.defaultProfile()
profile.setPersistentCookiesPolicy(QWebEngineProfile.ForcePersistentCookies)
browser_storage_folder = Path.home().as_posix() + '/.test_cookies'
profile.setPersistentStoragePath(browser_storage_folder)
webpage = QWebEnginePage(profile, self.webview)
self.webview.setPage(webpage)
self.webview.load(QUrl(site))
self.setCentralWidget(self.webview)
def closeEvent(self, event):
print('Close Event')
profile = QWebEngineProfile.defaultProfile()
profile.deleteLater()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

虽然上面的代码有效——如果你观看Cookie文件,你会看到它在页面加载后得到更新——但在页面加载之后,在文件中更新Cookie之前,几乎需要一整分钟的时间:

C:Users<My User Account>.test_cookiesCookies

如果在此之前关闭了窗口,则更新后的cookie将丢失。当PyQt5应用程序关闭时,如何强制cookiestore刷新到磁盘?我能在doc.qt.io上找到的提示是:

基于磁盘的QWebEngineProfile应在应用程序退出时或退出之前销毁,否则缓存和持久数据可能无法完全刷新到磁盘。

没有提示如何在Python中销毁QWebEngineProfile。对变量调用del没有任何作用。在配置文件上调用deleteLater也没有任何作用。更改代码以创建一个全新的配置文件self.profile = QWebEngineProfile("storage", self.webview),在任何地方都使用它,然后在closeEvent中调用self.profile.deleteLater()不会有任何作用。

我在邮件列表上收到了Florian Bruhin的回复。他的消息指出,我遇到的问题在PyQt 5.13中的一个可选的新退出方案中得到了解决,默认情况下在PyQt 5.14及更高版本中得到了处理。

旧版本有一个变通方法,我已经测试过了,效果很好。解决方法是从cookiestore中删除一个不存在的cookie,这会导致cookiestore立即刷新到磁盘:

cookie = QNetworkCookie()
QWebEngineProfile.defaultProfile().cookieStore().deleteCookie(cookie)

最新更新