使用 QtWebKit 在内存中渲染多个网页会在第二页中断,为啥?
Posted
技术标签:
【中文标题】使用 QtWebKit 在内存中渲染多个网页会在第二页中断,为啥?【英文标题】:Rendering multiple webpages in memory using QtWebKit breaks on second page, why?使用 QtWebKit 在内存中渲染多个网页会在第二页中断,为什么? 【发布时间】:2012-07-04 23:16:33 【问题描述】:我正在使用 PyQt4 的 QtWebKit 在内存中渲染网页,因为我需要执行 javascript,因为我需要检索嵌入式 Flash 视频元素。目前我使用的代码如下所示:
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import QWebSettings, QWebPage
class Render(QWebPage):
def __init__(self, url):
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
# Settings
s = self.settings()
s.setAttribute(QWebSettings.AutoLoadImages, False)
s.setAttribute(QWebSettings.JavascriptCanOpenWindows, False)
s.setAttribute(QWebSettings.PluginsEnabled, True)
self.loadFinished.connect(self._loadFinished)
self.mainFrame().load(QUrl(url))
self.app.exec_()
def _loadFinished(self, result):
self.frame = self.mainFrame()
self.app.quit()
def get_page_source(url):
r = Render(url)
html = r.frame.toHtml()
return html
现在这可以正常工作了,尽管初始化非常慢(需要 5-30 秒之间的任何时间开始),但它只适用于单个页面。这意味着在第一个网页上,我的最终输出如下所示:
<div>
<embed type="application/x-shockwave-flash" src="/player.swf" style="undefined" id="mediaplayer" name="mediaplayer" quality="high" allowfullscreen="true" wmode="opaque" flashvars="width=560&height=440&autostart=true&fullscreen=true&file=FILELINK"></embed>
</div>
但在连续尝试中,它看起来像这样:
<div>
<font>
<u>
<b>
<a href="http://get.adobe.com/flashplayer/">ATTENTION:<br>This video will not play. You currently do not have Adobe Flash installed on this computer. Please click here to download it (it's free!)
</a>
</b>
</u>
</font>
</div>
这里发生了什么我不知道的事情?
【问题讨论】:
您到底想检索什么 - 只是 'file=FILELINK'? @HughBothwell 是的,但这不是问题。我需要知道为什么它在连续尝试检索页面后会中断。 【参考方案1】:看起来您的 javascript 解释器只在第一页启动;第二个页面加载但永远不会运行它的javascript;但这与您的真正问题无关,即视频文件的名称隐藏在看起来像的代码块中
<script type="text/javascript">
var googleCode = 'czEuYWRkVmFyaWFibGUoImZpbGUiLCJodHRwOi8vd2lsbGlhbS5yaWtlci53aW1wLmNvbS9sb2FkdmlkZW8vMDA5YzUwMzNkZmYyMDQ3MmJiYzBjMjk2NmJjNzI2MjIvNGZmNGQ2ZDYvd2ViLXZpZGVvcy9iZTVjYWI2YjcxNmU0OWExZjFiYzc3NGNlMjVlZDg0Yl93YWtlci5mbHYiKTs=';
eval(lxUTILsign.decode(googleCode));
</script>
如果你调用一个javascript控制台并运行lxUTILsign.decode(googleCode);
你会得到
"s1.addVariable(\"file\",\"http://worf.wimp.com/loadvideo/2e368b70f8577ad167087530fc73748d/4ff4f5df/web-videos/35e78d1932b24f80ae3a9210fce008c4_titanic.flv\");"
坏消息是 lxUTILsign 被彻底混淆了; 好消息是,这无关紧要,因为它只是一个 base64 解码器,而 Python 已经有了一个(包括电池,宝贝!)。
import base64
import urllib2
import re
def get_video_url(page_url):
html = urllib2.urlopen(url).read()
match = re.search("googleCode = '(.*?)'", html)
if match is None:
raise ValueError('googleCode not found')
googleString = base64.b64decode(match.group(1))
match = re.search('","(.*?)"', googleString)
if match is None:
raise ValueError("didn't find video url")
return match.group(1)
url = 'http://www.wimp.com/titanicpiano/'
print get_video_url(url)
返回
http://worf.wimp.com/loadvideo/8656607f77689f759d54b4ec7207152d/4ff4ff9c/web-videos/35e78d1932b24f80ae3a9210fce008c4_titanic.flv
【讨论】:
Welp,这是一种方法,比实际呈现页面要快得多。我不知道它是从哪里获取网址的。非常感谢。以上是关于使用 QtWebKit 在内存中渲染多个网页会在第二页中断,为啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 QtWebkit 中,如何调用网页的 QNetworkAccessManager::createRequest()?