2016-02-25 32 views
1

我想在js执行后获取网站的DOM。 我也希望获得网站中iframe的所有内容,与我在Google Chrome的Inspect Element功能中获得的内容类似。如何获取网页的html dom及其框架

这是我的代码:

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,而不是I帧里面的HTML。有什么方法可以获取iframe的HTML吗?

回答

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_()) 

NB:您连接到主框架,而不是网络视图的loadFinished信号是非常重要的。如果你连接到后者,如果页面包含多个帧,它将被多次调用。

+0

是否有任何方法可以将所有加载到一个html文件中的帧附加到后面? – yuval

+0

@yuval。不,每一个都是一个单独的html文档。这实际上就是使用框架的关键 - 这样就可以将一个网页嵌入到另一个网页中。但是如果你想保存*完整*网页,框架只是问题的一部分 - 你还需要获取所有的脚本,样式表,图像等等。大多数现代浏览器都有内置的工具来完成此操作。在Firefox中,它是File> Save Page As> Web Page,完成。这将创建一个单独的html文档,以及一个包含大量关联文件的目录。 – ekhumoro