如何从JavaScript下载网页?

我如何从JavaScript呈现的网页链接下载? Python是首选语言。

到目前为止,我已经尝试在无头服务器上使用Selenium的Python绑定 。 这种方法非常缓慢,充满错误,不能可靠地确定下载进度或成功。 此外,无头服务器干扰我的剪贴板(这是一个问题)。 我使用Firefox,因为它可以configuration为下载到默认目录,但我不认为Chrome的情况是更好的。

另外,我试过使用WebKit。

def render(url): """Fully render a webpage (JavaScript and all) and return the HTML.""" import subprocess from textwrap import dedent script = dedent("""\ import sys from PyQt4.QtCore import QUrl from PyQt4.QtGui import QApplication from PyQt4.QtWebKit import QWebPage class Render(QWebPage): def __init__(self, url): self.app = QApplication(sys.argv) QWebPage.__init__(self) self.loadFinished.connect(self._loadFinished) self.mainFrame().load(QUrl(url)) self.app.exec_() def _loadFinished(self, result): self.frame = self.mainFrame() self.app.quit() render = Render(sys.argv[1]) print render.frame.toHtml().toAscii()""").encode() process = subprocess.Popen(['python2', '-', url], stderr=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE) # pipe script into Python's stdin return process.communicate(script)[0].decode('latin1') 

如果不是因为我需要下载进入同一个会话,这将是非常好的。 有没有办法保存用于呈现页面的会话? PyQt4和WebKit只是一堆共享库。 我不知道如何去摧毁他们的胆量,甚至是否有可能。

现在我只是做了以下几点:

 with requests.Session() as session: html = session.get(url).text link = get_url(html) download(link, session=session) 

没有深入细节, get_url(html, url)简单地从页面提取JavaScript,去除对DOM的任何调用,然后在node执行。 真是讨厌的东西…

任何方式,我可以安全地呈现一个网页,并保持会议?

如果Python不合适,或者JavaScript替代scheme更加优雅,我也可以在节点中完全做到这一点。 看起来也许node-dom可能就足够了? 我不是很熟悉它,但我对任何build议感兴趣。

在Python 2或3中的PyQt5在这种情况下做的伎俩。 请注意,该function过于复杂,以支持使用WebKit的早期版本的PyQt5以及使用WebEngine的更高版本。

 import sys def render(source_html): """Return rendered HTML.""" try: from PyQt5.QtCore import QEventLoop from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWidgets import QApplication class Render(QWebEngineView): """Render HTML with PyQt5 WebEngine.""" def __init__(self, html): self.html = None self.app = QApplication(sys.argv) QWebEngineView.__init__(self) self.loadFinished.connect(self._loadFinished) self.setHtml(html) while self.html is None: self.app.processEvents( QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents) self.app.quit() def _callable(self, data): self.html = data def _loadFinished(self, result): self.page().toHtml(self._callable) except ImportError: from PyQt5.QtWebKitWidgets import QWebPage from PyQt5.QtWidgets import QApplication class Render(QWebPage): """Render HTML with PyQt5 WebKit.""" def __init__(self, html): self.html = None self.app = QApplication(sys.argv) QWebPage.__init__(self) self.loadFinished.connect(self._loadFinished) self.mainFrame().setHtml(html) self.app.exec_() def _loadFinished(self, result): self.html = self.mainFrame().toHtml() self.app.quit() return Render(source_html).html 

或Python 2中的PyQt4。

 import sys from PyQt4.QtGui import QApplication from PyQt4.QtWebKit import QWebPage class Render(QWebPage): """Fully render HTML, JavaScript and all.""" def __init__(self, html): self.app = QApplication(sys.argv) QWebPage.__init__(self) self.loadFinished.connect(self._loadFinished) self.mainFrame().setHtml(html) self.app.exec_() def _loadFinished(self, result): self.frame = self.mainFrame() self.app.quit() render = Render(html) result = str(render.frame.toHtml().toAscii())