【问题标题】:PhantomJS stability when rendering multiple pages渲染多个页面时 PhantomJS 的稳定性
【发布时间】:2016-03-01 02:32:37
【问题描述】:
我在大量页面上运行 PhantomJS 以抓取一些特定的 JS 生成的内容。我正在使用 Python Selenium 绑定,使用它可以轻松地对结果执行 XPath 查询。我注意到,如果我尝试实例化单个 webdriver.PhantomJS 对象并使用它执行整个工作(可以说是“重用”它),我的脚本很快就会变得不稳定,出现零星的内存和连接问题。我的下一个尝试是尝试为每个渲染调用实例化一个新驱动程序(并在完成后调用quit()),这对于多个请求也不起作用。我最后的尝试是使用subprocess 将渲染调用隔离在它自己的进程空间中。但即使使用这种技术,这是迄今为止最稳定的,我仍然需要将我的整个脚本包装在supervisor 中,以处理偶尔出现的问题。我真的想知道我是否做错了什么,或者是否有什么我应该注意的。我知道 PhantomJS(和其他自动浏览器)本身并不是真正用于抓取(更多用于测试),但是有没有办法让它以极高的稳定性工作?
【问题讨论】:
标签:
python
selenium
phantomjs
stability
【解决方案1】:
我在普通浏览器中使用 Selenium 和 pyvirtualdisplay,方式类似于:Python - Headless Selenium WebDriver Tests using PyVirtualDisplay(尽管我使用的是 Chrome;只是驱动程序不同而已)。
比我在 node 和 Python 中使用 PhantomJS 的经验要稳定得多。以防万一,您仍然可能希望使用流程管理器,但这种方式对我来说不太容易出错。
另外,我建议编写一个小的 Python 包装类,以便您可以使用 with 块并确保您的环境始终得到清理;如果您没有适当地终止会话,最终可能会导致孤立的浏览器占用内存。
来自我的项目:
import os, time
from selenium import webdriver
from pyvirtualdisplay import Display
class ChromeSession(object):
def __enter__(self):
self.display = Display(visible=0, size=(1024, 768))
self.display.start()
chromedriver = "/usr/lib/chromium/chromedriver"
os.environ["websession.chrome.driver"] = chromedriver
self.driver = webdriver.Chrome(chromedriver)
# Tell the driver to wait (if necessary) in case UI rendering takes a while...
self.driver.implicitly_wait(5)
return self.driver
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
print exc_type, exc_val
print exc_tb
self.driver.quit()
self.display.stop()