从 QWebEngineView 获取 PDF 文件的链接

Posted

技术标签:

【中文标题】从 QWebEngineView 获取 PDF 文件的链接【英文标题】:Getting the link to PDF files from QWebEngineView 【发布时间】:2021-08-11 19:35:53 【问题描述】:

我正在使用 QWebEngineView 并发现在尝试单击 pdf 文件链接时它不会打开该文件。我发现 QWebEngineView 无法自行显示 pdf 文件。通过一些研究,我现在可以下载 pdf 文件并自行显示它们,但是我需要能够从 QWebEngineView 获取 pdf 文件的链接才能知道要下载哪个文件。问题是.url()函数只返回当前网页的url,似乎不受我点击pdf文件链接的影响,我找不到任何其他方法来获取pdf文件的链接文件。关于如何获取pdf文件链接的任何想法?任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

您可以使用javascript获取所有链接,然后按扩展名过滤:

import sys

from PyQt5.QtCore import QCoreApplication, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView


def main():
    app = QApplication(sys.argv)

    url = QUrl("https://www.princexml.com/samples/")
    view = QWebEngineView()

    def callback(links):
        for link in links:
            if link.endswith(".pdf"):
                print(link)
            QCoreApplication.quit()

    def handle_load_finished(ok):
        if ok:
            view.page().runJavaScript(
                """
  (function() 
    // https://***.com/a/3824292/6622587
    var urls = [];
    for(var i = document.links.length; i --> 0;)
        if(document.links[i].hostname === location.hostname)
            urls.push(document.links[i].href);
    return urls;
  )();""",
                callback,
            )

    view.loadFinished.connect(handle_load_finished)
    view.load(url)
    view.resize(640, 480)
    view.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

输出:

http://www.princexml.com/howcome/2016/samples/magic6/magic.pdf
http://www.princexml.com/howcome/2016/samples/magic6/magic.pdf
https://www.princexml.com/samples/flyer/flyer.pdf
https://www.princexml.com/samples/flyer/flyer.pdf
https://www.princexml.com/samples/catalog/PrinceCatalogue.pdf
https://www.princexml.com/samples/catalog/PrinceCatalogue.pdf
http://www.princexml.com/howcome/2016/samples//malthus/essay.pdf
http://www.princexml.com/howcome/2016/samples//malthus/essay.pdf
http://www.princexml.com/howcome/2016/samples/magic8/index.pdf
http://www.princexml.com/howcome/2016/samples/magic8/index.pdf
http://www.princexml.com/howcome/2016/samples/invoice/index.pdf
https://www.princexml.com/samples/invoice/invoicesample.pdf
http://www.princexml.com/howcome/2016/samples/invoice/index.pdf
https://www.princexml.com/samples/invoice/invoicesample.pdf

更新:

如果您想下载 PDF,则无需执行上述操作,因为 QWebEngineView 确实允许下载。

import sys

from PyQt5.QtCore import QCoreApplication, QFileInfo, QUrl
from PyQt5.QtWidgets import QApplication, QFileDialog
from PyQt5.QtWebEngineWidgets import QWebEngineView


def handle_download_erequested(download):
    download.downloadProgress.connect(print)
    download.stateChanged.connect(print)
    download.finished.connect(lambda: print("download finished"))
    old_path = download.url().path()  # download.path()
    suffix = QFileInfo(old_path).suffix()
    path, _ = QFileDialog.getSaveFileName(None, "Save File", old_path, "*." + suffix)
    if path:
        download.setPath(path)
        download.accept()


def main():
    app = QApplication(sys.argv)

    url = QUrl("https://www.princexml.com/samples/")
    view = QWebEngineView()

    view.page().profile().downloadRequested.connect(handle_download_erequested)
    view.load(url)
    view.resize(640, 480)
    view.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

QWebEngineView 也有一个 PDF 查看器

import sys

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets


def main():

    print(
        f"PyQt5 version: QtCore.PYQT_VERSION_STR, Qt version: QtCore.QT_VERSION_STR"
    )

    app = QtWidgets.QApplication(sys.argv)
    view = QtWebEngineWidgets.QWebEngineView()
    settings = view.settings()
    settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled, True)
    url = QtCore.QUrl("https://www.princexml.com/samples/invoice/invoicesample.pdf")
    view.load(url)
    view.resize(640, 480)
    view.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

【讨论】:

您好,非常感谢您的回答,有没有办法可以使这个特定于我点击的链接,我希望能够点击一个链接,然后下载该 pdf,我是不确定如何获取我点击的 pdf 链接。 @blunty6363 你好像有一个XY问题,检查我的更新。 非常感谢您的帮助。然而,我现在有一个非常奇怪的问题。我在我的问题中添加了一些代码,这些代码负责创建我的 QWebEngineView。我的问题是,如果我保持原样保留代码(注释掉一行),那么我可以使用查看器打开 pdf 文件,但是在尝试打开 youtube 时程序崩溃,但如果我取消注释并将该行放入程序中,youtube 不再崩溃,但我无法再打开 pdf 文件。知道为什么会发生这种情况以及任何解决方案吗? @blunty6363 您不应该更改您的帖子,您不会询问 pdfviewer(这只是我的演示),而是如何获取链接。如果您还有其他问题,请创建一个新帖子。如果您使用我的 pdfviewer 中的代码,您是否有同样的问题?请阅读How to Ask 并查看tour

以上是关于从 QWebEngineView 获取 PDF 文件的链接的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Qt QWebEngineView 获取 HTTP 状态码?

从 js QWebEngineView 获取变量到 python

QWebEngineView 在外部浏览器中打开

在QWebEngineView中获取sslerrors信号

如何将 swf 文件从内存加载到 QWebEngineView

使用QWebEngineView显示html时如何获取verticalScrollBar的最大值和当前值