如何从JavaScript呈现的网页上的链接下载? Python是首选语言。
到目前为止,我已尝试在无头服务器上使用Python bindings for Selenium。这种方法非常慢,充满了错误,无法可靠地确定下载进度或成功。此外,无头服务器干扰我的剪贴板(这是一个问题)。我使用Firefox,因为它可以配置为下载到默认目录,但我不认为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替代方案更优雅,我也愿意在节点中完全完成它。看起来node-dom可能就足够了?我不是很熟悉它,但我对任何建议感兴趣。
答案 0 :(得分:-1)
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())