我想在Python中使用PhantomJS。我用谷歌搜索了这个问题,但找不到合适的解决办法。

我发现os.popen()可能是一个不错的选择。但是我不能给它传递一些参数。

现在使用subprocess.Popen()可能是一个合适的解决方案。我想知道是否有更好的解决办法。

有办法在Python中使用PhantomJS吗?


当前回答

如果您正在使用Buildout,您可以轻松地自动化Pykler使用gp.recipe.node配方描述的安装过程。

[nodejs]
recipe = gp.recipe.node
version = 0.10.32
npms = phantomjs
scripts = phantomjs

这部分将node.js安装为二进制文件(至少在我的系统上),然后使用npm安装PhantomJS。最后它创建了一个入口点bin/phantomjs,你可以用它来调用phantomjs的webdriver。(要安装Selenium,您需要在您的egg需求或Buildout配置中指定它。)

driver = webdriver.PhantomJS('bin/phantomjs')

其他回答

@Pykler的回答很好,但是Node的要求已经过时了。这个回答中的评论给出了一个更简单的答案,我把它放在这里是为了节省别人的时间:

Install PhantomJS As @Vivin-Paliath points out, it's a standalone project, not part of Node. Mac: brew install phantomjs Ubuntu: sudo apt-get install phantomjs etc Set up a virtualenv (if you haven't already): virtualenv mypy # doesn't have to be "mypy". Can be anything. . mypy/bin/activate If your machine has both Python 2 and 3 you may need run virtualenv-3.6 mypy or similar. Install selenium: pip install selenium Try a simple test, like this borrowed from the docs: from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.PhantomJS() driver.get("http://www.python.org") assert "Python" in driver.title elem = driver.find_element_by_name("q") elem.clear() elem.send_keys("pycon") elem.send_keys(Keys.RETURN) assert "No results found." not in driver.page_source driver.close()

如果您正在使用Buildout,您可以轻松地自动化Pykler使用gp.recipe.node配方描述的安装过程。

[nodejs]
recipe = gp.recipe.node
version = 0.10.32
npms = phantomjs
scripts = phantomjs

这部分将node.js安装为二进制文件(至少在我的系统上),然后使用npm安装PhantomJS。最后它创建了一个入口点bin/phantomjs,你可以用它来调用phantomjs的webdriver。(要安装Selenium,您需要在您的egg需求或Buildout配置中指定它。)

driver = webdriver.PhantomJS('bin/phantomjs')

PhantomJS最近完全放弃了对Python的支持。然而,PhantomJS现在嵌入了幽灵驱动程序。

一个新的项目填补了这一空白:ghost.py。你可能想用它来代替:

from ghost import Ghost
ghost = Ghost()

with ghost.start() as session:
    page, extra_resources = ghost.open("http://jeanphi.me")
    assert page.http_status==200 and 'jeanphix' in ghost.content

这就是我所做的,python3.3。我正在处理庞大的站点列表,因此超时失败对于工作运行整个列表是至关重要的。

command = "phantomjs --ignore-ssl-errors=true "+<your js file for phantom>
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

# make sure phantomjs has time to download/process the page
# but if we get nothing after 30 sec, just move on
try:
    output, errors = process.communicate(timeout=30)
except Exception as e:
    print("\t\tException: %s" % e)
    process.kill()

# output will be weird, decode to utf-8 to save heartache
phantom_output = ''
for out_line in output.splitlines():
    phantom_output += out_line.decode('utf-8')

下面是我如何使用PhantomJS和Django测试javascript:

移动/ test_no_js_errors.js:

var page = require('webpage').create(),
    system = require('system'),
    url = system.args[1],
    status_code;

page.onError = function (msg, trace) {
    console.log(msg);
    trace.forEach(function(item) {
        console.log('  ', item.file, ':', item.line);
    });
};

page.onResourceReceived = function(resource) {
    if (resource.url == url) {
        status_code = resource.status;
    }
};

page.open(url, function (status) {
    if (status == "fail" || status_code != 200) {
        console.log("Error: " + status_code + " for url: " + url);
        phantom.exit(1);
    }
    phantom.exit(0);
});

移动/ tests.py:

import subprocess
from django.test import LiveServerTestCase

class MobileTest(LiveServerTestCase):
    def test_mobile_js(self):
        args = ["phantomjs", "mobile/test_no_js_errors.js", self.live_server_url]
        result = subprocess.check_output(args)
        self.assertEqual(result, "")  # No result means no error

运行测试:

py测试移动设备