【问题标题】:How to get the html dom of a webpage and its frames如何获取网页的 html dom 及其框架
【发布时间】:2016-02-25 13:45:35
【问题描述】:

我想在 js 执行后获取一个网站的 DOM。 我还想获取网站中 iframe 的所有内容,类似于我在 Google Chrome 的 Inspect Element 功能中的内容。

这是我的代码:

import sys
from PyQt4 import QtGui, QtCore, QtWebKit

class Sp():
  def save(self):
    print ("call")
    data = self.webView.page().currentFrame().documentElement().toInnerXml()
    print(data.encode('utf-8'))
    print ('finished')
  def main(self):
    self.webView = QtWebKit.QWebView()
    self.webView.load(QtCore.QUrl("http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe_scrolling"))
    QtCore.QObject.connect(self.webView,QtCore.SIGNAL("loadFinished(bool)"),self.save)

app = QtGui.QApplication(sys.argv)
s = Sp()
s.main()
sys.exit(app.exec_())

这给了我网站的 html,但不是 iframe 中的 html。有什么方法可以获取 iframe 的 HTML。

【问题讨论】:

    标签: python iframe pyqt pyqt4 qwebkit


    【解决方案1】:

    一般来说,这是一个很难解决的问题。

    主要的困难是没有办法提前知道每个页面有多少帧。除此之外,每个子帧可能有自己的一组帧,其数量也是未知的。理论上,嵌套框架的数量可能是无限的,并且页面永远不会完成加载(对于有大量广告的网站来说,这似乎并不夸张)。

    无论如何,下面是您的脚本的一个版本,它在加载时获取每个帧的顶级 QWebFrame 对象,并显示如何访问您感兴趣的一些内容。正如您将从输出,有很多广告插入的“垃圾”帧,你需要以某种方式过滤掉。

    import sys, signal
    from PyQt4 import QtGui, QtCore, QtWebKit
    
    class Sp():
      def save(self, ok, frame=None):
        if frame is None:
            print ('main-frame')
            frame = self.webView.page().mainFrame()
        else:
            print('child-frame')
        print('URL: %s' % frame.baseUrl().toString())
        print('METADATA: %s' % frame.metaData())
        print('TAG: %s' % frame.documentElement().tagName())
        print()
    
      def handleFrameCreated(self, frame):
        frame.loadFinished.connect(lambda: self.save(True, frame=frame))
    
      def main(self):
        self.webView = QtWebKit.QWebView()
        self.webView.page().frameCreated.connect(self.handleFrameCreated)
        self.webView.page().mainFrame().loadFinished.connect(self.save)
        self.webView.load(QtCore.QUrl("http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe_scrolling"))
    
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    print('Press Crtl+C to quit\n')
    app = QtGui.QApplication(sys.argv)
    s = Sp()
    s.main()
    sys.exit(app.exec_())
    

    注意:连接到主机loadFinished信号而不是网络视图很重要。如果连接到后者,如果页面包含多于一帧,则会被多次调用。

    【讨论】:

    • 有什么方法可以在之后将我加载到一个 html 文件中的所有框架附加到一个 html 文件中?
    • @yuval。不,每个都是一个单独的 html 文档。这就是使用框架的真正意义所在——这样您就可以将一个网页嵌入到另一个网页中。但是如果你想保存完整的网页,框架只是问题的一部分——你还需要获取所有的脚本、样式表、图像等等。大多数现代浏览器都有内置的功能来执行此操作。在Firefox中,它是文件>另存为>网页,完成。这将创建一个 html 文档,以及一个包含一大堆相关文件的目录。
    猜你喜欢
    • 2020-01-16
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多