有没有办法在Python中使用PhantomJS?


203

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

我发现os.popen() 可能是一个不错的选择。但是我无法通过一些争论。

使用subprocess.Popen()可能是目前合适的解决方案。我想知道是否有更好的解决方案。

有没有办法在Python中使用PhantomJS?


我在下面的答案告诉您如何做。只是看您的问题,实际上就是Selenium的功能,subprocess.popen但是有一些扩展功能可以使api无缝。
皮克勒2015年

@flyer:您可能应该考虑更改接受的答案,请参见下文。谢谢。
dotancohen

Answers:


373

在python中使用PhantomJS的最简单方法是通过Selenium。最简单的安装方法是

  1. 安装NodeJS
  2. 使用Node的包管理器安装phantomjs: npm -g install phantomjs-prebuilt
  3. 安装硒(如果使用的话,在您的virtualenv中)

安装后,您可以简单地使用phantom:

from selenium import webdriver

driver = webdriver.PhantomJS() # or add to your PATH
driver.set_window_size(1024, 768) # optional
driver.get('https://google.com/')
driver.save_screenshot('screen.png') # save a screenshot to disk
sbtn = driver.find_element_by_css_selector('button.gbqfba')
sbtn.click()

如果您的系统路径环境变量设置不正确,则需要指定确切的路径作为的参数webdriver.PhantomJS()。替换为:

driver = webdriver.PhantomJS() # or add to your PATH

...具有以下内容:

driver = webdriver.PhantomJS(executable_path='/usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs')

参考文献:


40
这工作得很漂亮,并且可能为我节省了几天。谢谢。如果希望将整个呈现的页面作为源,则为driver.page_source
scharfmn 2013年

4
这样确实漂亮,而且我感到惊喜,因为phantomjs.org/faq.html说:“不是的Node.js模块” --yet在故宫包装npmjs.org/package/phantomjs使得它表现了这一目的。就我而言,我想这样做:bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")并且...奏效了!
MarkHu

8
我同意ghost具有疯狂的依赖关系,即使安装了数百万个X11相关的库,我实际上也无法启动和运行它。鬼是一个恐怖的故事。
皮克勒

5
@phabtar您需要将路径传递给phantomjs作为PhantomJS的第一个参数...或修复Windows syspath以便能够看到phantomjs。
皮克勒2013年

2
愚蠢的问题:为什么我必须安装node-js?还有没有其他方法可以得到幻影?
艾尔多萨(Eildosa)2015年

80

PhantomJS最近完全放弃了对Python的支持。但是,PhantomJS现在嵌入了Ghost驱动程序

此后,一个新项目已加紧填补了空白: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

21
即使放弃了支持,我也发现安装npm(节点程序包管理器)并使用它来安装最新的phantomjs(具有webdriver支持)并在python中安装硒……比试图使PyQT或PySide正常工作要容易得多。关于phantom的好处是它确实没有头,并且不需要与UI / X11相关的库即可工作。
皮克勒

12
在尝试使用ghost.py并讨厌自己的生活后,我在下面添加了一个答案,解释了我的首选解决方案
Pykler 2013年

8
皮克勒(Pykler)的“讨厌我的生活”并不是轻描淡写。如果有人将这个问题的“正确答案”更改为Pykler's,我将省去一天的工作。
YPCrumble 2013年

2
@YPCrumble:不幸的是,只有OP才能做到;更改接受的答案。
马丁·彼得斯

3
在今天早晨尝试了许多不同的方法之后,@ Pykler解决方案最终以最流畅的方式工作。
andyzinsser

40

现在,由于GhostDriver与PhantomJS捆绑在一起,通过Selenium使用它变得更加方便。

我按照Pykler的建议尝试了PhantomJS的Node安装,但实际上,我发现它比PhantomJS的独立安装要慢。我猜独立安装没有早些时候提供这些功能,但是从v1.9开始,它确实提供了这些功能。

  1. 安装PhantomJS(http://phantomjs.org/download.html)(如果您使用的是Linux,则以下说明将有助于https://stackoverflow.com/a/14267295/382630
  2. 使用pip安装Selenium。

现在您可以像这样使用

import selenium.webdriver
driver = selenium.webdriver.PhantomJS()
driver.get('http://google.com')
# do some processing

driver.quit()

3
特别感谢您指出有关在Ubuntu上安装PhantomJS的答案,它对我有所帮助。
丹尼斯·哥洛马佐夫

我刚学到的一种安装Selenium的快速方法是,在Windows上键入:C:\ Python34 \ Scripts \ pip.exe install Selenium。
ntk4

8

这是我使用PhantomJS和Django测试javascript的方法:

mobile / 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);
});

mobile / 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

运行测试

manage.py test mobile


谢谢。我使用subprocess.Popen调用phantomjs脚本和它的工作:)
传单

您确实看到这是有限的吧?您正在做的只是做一个shell调用来执行phantomjs-您实际上并没有使用“适当的”接口,您可以通过该接口正确地处理异常,阻塞等
。– kamelkev

@kamelkev:我知道这是如何限制的。好的方面是,这种方法使我可以使用Django的引导功能来为每个测试建立具有正确内容的测试数据库。是的,可以将其与其他答案结合使用以达到两全其美的效果。
EmilStenström13年

6

@Pykler答案很好,但是Node要求已经过时。该答案中的注释提出了更简单的答案,我将其放在此处以节省其他人的时间:

  1. 安装PhantomJS

    正如@ Vivin-Paliath所指出的,这是一个独立的项目,不是Node的一部分。

    苹果电脑:

    brew install phantomjs

    Ubuntu:

    sudo apt-get install phantomjs

    等等

  2. 设置一个virtualenv(如果还没有的话):

    virtualenv mypy  # doesn't have to be "mypy". Can be anything.
    . mypy/bin/activate

    如果您的计算机同时具有Python 2和3,则可能需要运行virtualenv-3.6 mypy或类似版本。

  3. 安装硒:

    pip install selenium
  4. 尝试一个简单的测试,例如从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()

如何PhantomJS在Windows 上安装?使用pip命令似乎不起作用。
MD。Khairul Basar

1
Pip是python软件包安装程序,因此它可与selenium一起使用,它可以作为python软件包使用。PhantomJS不是python包,因此不能与pip一起使用。我为“ PhantomJS install windows”做了一个快速的google搜索,点击率很高。
Andrew E

5

这就是我所做的,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')

谢谢,我能够根据自己的目的将其更改为口味。
iChux

5

如果使用Anaconda,请安装:

conda install PhantomJS

在您的脚本中:

from selenium import webdriver
driver=webdriver.PhantomJS()

完美地工作。


到目前为止,默认通道不包含适用于linux64的PhantomJS
Eugene Pakhomov

该死的,我喜欢conda <3,这太容易了。我在osx上。
O.rka'1

1

如果您使用的是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,您需要在鸡蛋要求或Buildout配置中指定它。)

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

1
使用buildout自动化安装过程的另一种方法是使用gp.recipe.phantomjs,它配置phantomjscasperjs
gakhov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.