我在一大堆页面上运行 PhantomJS 来抓取一些特定的 JS 生成的内容。我正在使用 Python Selenium 绑定,使用它可以轻松地对结果执行 XPath 查询。我注意到,如果我尝试实例化一个webdriver.PhantomJS
对象并用它执行整个工作(可以说是“重用”它),我的脚本很快就会变得不稳定,出现零星的内存和连接问题。我的下一个尝试是尝试为每个渲染调用实例化一个新驱动程序(并quit()
在完成时调用它),这对于多个请求也不起作用。我最后的尝试是用来subprocess
隔离渲染调用在它自己的进程空间中。但即使使用这种技术,这是迄今为止最稳定的,我仍然需要将整个脚本包装在supervisor
,以处理偶尔的打嗝。我真的想知道我是否做错了什么,或者是否有什么我应该注意的。我知道 PhantomJS(和其他自动浏览器)本身并不是真正用于抓取(更多用于测试),但是有没有办法让它以很高的稳定性工作呢?
问问题
260 次
1 回答
1
我pyvirtualdisplay
以类似于以下方式将 Selenium 与普通浏览器一起使用: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()
于 2016-03-01T04:26:26.060 回答