Есть ли способ использовать PhantomJS в Python?

203

Я хочу использовать PhantomJS в Python . Я погуглил эту проблему, но не смог найти правильных решений.

Я считаю, os.popen() может быть хорошим выбором. Но я не мог передать некоторые аргументы этому.

Использование subprocess.Popen()может быть правильным решением на данный момент. Я хочу знать, есть ли лучшее решение или нет.

Есть ли способ использовать PhantomJS в Python?

листовка
источник
Мой ответ ниже говорит вам, как это сделать. Просто посмотрите на ваш вопрос, и это именно то, что делает Selenium, subprocess.popenно с некоторыми расширенными функциями, чтобы сделать API гладким.
Пиклер
@flyer: Вам, вероятно, следует подумать об изменении принятого ответа, см. ниже. Спасибо.
Dotancohen

Ответы:

373

Самый простой способ использовать PhantomJS в Python - это через Selenium. Самый простой способ установки

  1. Установить NodeJS
  2. Используя менеджер пакетов Node, установите phantomjs: npm -g install phantomjs-prebuilt
  3. установить селен (в вашем virtualenv, если вы его используете)

После установки вы можете использовать фантом так же просто, как:

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')

Ссылки:

Pykler
источник
40
Это работало прекрасно и, вероятно, спасло мне дни. Спасибо. Если кто-то хочет, чтобы вся визуализированная страница вернулась в качестве источника, это так driver.page_source.
scharfmn
4
Это прекрасно работает, и я приятно удивлен, потому что phantomjs.org/faq.html говорит «не модуль Node.js» - однако оболочка npm в npmjs.org/package/phantomjs заставляет его вести себя для этой цели. В моем случае я хотел сделать это: bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")и ... это сработало!
MarkHu
8
Я согласен, что у ghost есть сумасшедшие зависимости, и я фактически не смог его запустить и запустить даже после установки миллионов связанных с X11 библиотек. Призрак - это ужасная история.
Пиклер
5
@phabtar Вам нужно указать путь к phantomjs в качестве первого аргумента для PhantomJS ... или исправить системный путь Windows, чтобы видеть фантомы.
Пиклер
2
Тупой вопрос: зачем мне устанавливать node-js? нет ли другого способа получить pahantomJs?
Eildosa
80

PhantomJS недавно полностью отказался от поддержки Python . Тем не менее, PhantomJS теперь встраивает Ghost Driver .

С тех пор появился новый проект, чтобы заполнить пустоту 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 (с поддержкой веб-драйверов) и установки selenium in python ... гораздо проще, чем пытаться заставить PyQT или PySide работать должным образом. Что приятно в фантоме, он действительно безголовый и не требует никаких связанных с UI / X11 библиотек для работы.
Пиклер
12
Я добавил ответ ниже, объясняя мое предпочтительное решение после попытки использовать ghost.py и ненавидя свою жизнь
Пиклер,
8
«Ненависть моей жизни» Пиклера не является преуменьшением. Если бы кто-то заменил «правильный ответ» на этот вопрос на вопрос Пиклера, я бы сэкономил день усилий.
YPCrumble
2
@YPCrumble: к сожалению, только ОП может сделать это; изменить принятый ответ.
Мартин Питерс
3
Попробовав несколько разных подходов сегодня утром, решение @Pykler в итоге сработало максимально гладко.
andyzinsser
40

Теперь, когда GhostDriver поставляется в комплекте с PhantomJS, стало еще удобнее использовать его через Selenium.

Я попробовал установить Node в PhantomJS, как предложил Pykler, но на практике я обнаружил, что он медленнее, чем автономная установка PhantomJS. Я полагаю, что автономная установка не предоставляла эти возможности ранее, но в версии 1.9 она так и делает.

  1. Установите PhantomJS ( http://phantomjs.org/download.html ) (если вы работаете в Linux, следующие инструкции помогут https://stackoverflow.com/a/14267295/382630 )
  2. Установите Selenium с помощью pip.

Теперь вы можете использовать как это

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

driver.quit()
Панкай
источник
3
Отдельное спасибо за указание на SO ответ относительно установки PhantomJS на Ubuntu, это помогло мне.
Денис Голомазов
быстрый способ установить Selenium, который я только что узнал, в Windows: C: \ Python34 \ Scripts \ pip.exe установить Selenium.
ntk4
8

Вот как я тестирую javascript с использованием PhantomJS и Django:

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, и это сработало :)
flyer
Вы видите, как это ограничено, верно? Все, что вы делаете, это делаете вызов оболочки для выполнения phantomjs - вы на самом деле не используете «правильный» интерфейс, через который вы можете правильно обрабатывать исключения, блокировку и т. Д.
kamelkev
@ kamelkev: я вижу, как это ограничено. Плюс в том, что этот метод позволяет мне использовать возможности начальной загрузки Django для настройки тестовой базы данных с правильным содержанием для каждого теста. И да, это может быть объединено с другими ответами, чтобы получить лучшее из обоих миров.
Эмиль Стенстрём
6

Ответ на @Pykler является большим , но требование Node устарел. Комментарии в этом ответе предлагают более простой ответ, который я поставил здесь, чтобы сэкономить время других:

  1. Установить PhantomJS

    Как указывает @ Vivin-Paliath, это отдельный проект, а не часть Node.

    Mac:

    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. Попробуйте простой тест, например, заимствованный из документации :

    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команды.
доктор медицинских наук Хайрул Басар
1
Pip - это установщик пакета python, поэтому он работает с selenium, который доступен в виде пакета python. PhantomJS не является пакетом Python, поэтому не будет работать с pip. Я сделал быстрый Google для «Windows установки PhantomJS», и есть хорошие хиты.
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')
TLIB
источник
Спасибо, я смог изменить его по своему вкусу.
iChux
5

Если вы используете Anaconda, установите с:

conda install PhantomJS

в вашем скрипте:

from selenium import webdriver
driver=webdriver.PhantomJS()

работает отлично.

clg4
источник
На данный момент каналы по умолчанию не содержат PhantomJS для linux64
Евгений Пахомов
Черт, я люблю Конду <3, это было так легко. я на оссе.
O.rka
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. (Чтобы установить Selenium, вам нужно указать его в требованиях к яйцам или в конфигурации Buildout.)

driver = webdriver.PhantomJS('bin/phantomjs')
Денис Дрешер
источник
1
еще один способ автоматизации процесса установки с помощью buildout, который он просто использует gp.recipe.phantomjs, который настраивает phantomjsиcasperjs
gakhov