Gibt es eine Möglichkeit, PhantomJS in Python zu verwenden?


203

Ich möchte PhantomJS in Python verwenden . Ich habe dieses Problem gegoogelt, konnte aber keine richtigen Lösungen finden.

Ich finde os.popen() vielleicht eine gute Wahl. Aber ich konnte einige Argumente nicht weitergeben.

Die Verwendung subprocess.Popen()kann vorerst eine geeignete Lösung sein. Ich möchte wissen, ob es eine bessere Lösung gibt oder nicht.

Gibt es eine Möglichkeit, PhantomJS in Python zu verwenden?


Meine Antwort unten zeigt Ihnen, wie es geht. Schauen Sie sich nur Ihre Frage an und genau das macht Selenium, subprocess.popenaber mit einigen erweiterten Funktionen, um die API nahtlos zu machen.
Pykler

@flyer: Sie sollten wahrscheinlich in Betracht ziehen, die akzeptierte Antwort zu ändern, siehe unten. Danke dir.
Dotancohen

Antworten:


373

Der einfachste Weg, PhantomJS in Python zu verwenden, ist über Selen. Die einfachste Installationsmethode ist

  1. Installieren Sie NodeJS
  2. Installieren Sie mit dem Paketmanager von Node Phantomjs: npm -g install phantomjs-prebuilt
  3. Installieren Sie Selen (in Ihrer virtuellen Umgebung, wenn Sie diese verwenden).

Nach der Installation können Sie Phantom so einfach verwenden wie:

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

Wenn Ihre Systempfad-Umgebungsvariable nicht richtig festgelegt ist, müssen Sie den genauen Pfad als Argument für angeben webdriver.PhantomJS(). Ersetzen Sie dies:

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

... mit den folgenden:

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

Verweise:


40
Das hat wunderbar funktioniert und mir wahrscheinlich Tage gespart. Danke dir. Wenn man die gesamte gerenderte Seite als Quelle zurück haben möchte, ist es driver.page_source.
scharfmn

4
Dies funktioniert wunderbar und ich bin angenehm überrascht, weil phantomjs.org/faq.html "kein Node.js-Modul" sagt - obwohl der npm-Wrapper unter npmjs.org/package/phantomjs dafür sorgt, dass es sich für diesen Zweck verhält. In meinem Fall wollte ich das machen: bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")und ... es hat funktioniert!
MarkHu

8
Ich bin damit einverstanden, dass Ghost verrückte Abhängigkeiten hat, und ich konnte es selbst nach der Installation von Millionen von X11-bezogenen Bibliotheken nicht zum Laufen bringen. Ghost ist eine Horrorgeschichte.
Pykler

5
@phabtar Sie müssen den Pfad an phantomjs als erstes Argument an PhantomJS übergeben ... oder Ihren Windows-Systempfad korrigieren, um Phantomjs sehen zu können.
Pykler

2
Dumme Frage: Warum muss ich Node-Js installieren? Gibt es keinen anderen Weg, um PahantomJs zu bekommen?
Eildosa

80

PhantomJS hat kürzlich die Python-Unterstützung ganz eingestellt. PhantomJS bettet jetzt jedoch Ghost Driver ein .

Seitdem ist ein neues Projekt hinzugekommen, um die Lücke zu füllen: ghost.py . Sie möchten das wahrscheinlich stattdessen verwenden:

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
Obwohl die Unterstützung eingestellt wurde, stellte ich fest, dass die Installation von npm (Node Package Manager) und die Installation der neuesten Phantomjs (mit Webdriver-Unterstützung) und die Installation von Selen in Python viel einfacher ist als der Versuch, PyQT oder PySide zum ordnungsgemäßen Funktionieren zu bringen. Das Schöne an Phantom ist, dass es wirklich kopflos ist und keine UI / X11-bezogenen Bibliotheken benötigt, um zu funktionieren.
Pykler

12
Ich habe unten eine Antwort hinzugefügt, die meine bevorzugte Lösung erklärt, nachdem ich versucht habe, ghost.py zu verwenden und mein Leben zu hassen
Pykler

8
Pyklers "mein Leben hassen" ist keine Untertreibung. Wenn jemand die "richtige Antwort" für diese Frage in Pyklers ändern würde, hätte ich mir einen Tag Mühe gespart.
YPCrumble

2
@YPCrumble: Leider kann das nur das OP; Ändern Sie die akzeptierte Antwort.
Martijn Pieters

3
Nachdem wir heute Morgen verschiedene Ansätze ausprobiert hatten, funktionierte die @ Pykler-Lösung am reibungslosesten.
Andyzinsser

40

Seit der GhostDriver im Lieferumfang des PhantomJS enthalten ist, ist die Verwendung über Selenium noch komfortabler geworden.

Ich habe die Node-Installation von PhantomJS ausprobiert, wie von Pykler vorgeschlagen, aber in der Praxis war sie langsamer als die eigenständige Installation von PhantomJS. Ich denke, die eigenständige Installation hat diese Funktionen früher nicht bereitgestellt, aber ab Version 1.1 ist dies sehr wichtig.

  1. Installieren Sie PhantomJS ( http://phantomjs.org/download.html ) (Wenn Sie unter Linux arbeiten, helfen die folgenden Anweisungen https://stackoverflow.com/a/14267295/382630 )
  2. Installieren Sie Selen mit pip.

Jetzt können Sie so verwenden

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

driver.quit()

3
Besonderer Dank für den Hinweis auf SO Antwort bezüglich der PhantomJS-Installation unter Ubuntu, es hat mir geholfen.
Dennis Golomazov

Eine schnelle Möglichkeit, Selenium zu installieren, die ich gerade gelernt habe, besteht darin, unter Windows Folgendes einzugeben: C: \ Python34 \ Scripts \ pip.exe Selenium installieren.
Ntk4

8

So teste ich Javascript mit PhantomJS und 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

Führen Sie Tests durch :

manage.py test mobile


Vielen Dank. Ich benutzte subprocess.Popen das PhantomJS Skript aufrufen und es funktionierte :)
Flyer

Sie sehen, wie begrenzt das ist, oder? Alles, was Sie tun, ist einen Shell-Aufruf, um Phantomjs auszuführen - Sie verwenden tatsächlich keine "richtige" Schnittstelle, über die Sie Ausnahmen, Blockierungen usw. ordnungsgemäß behandeln können
Kamelkev

@kamelkev: Ich sehe, wie begrenzt dies ist. Der Vorteil ist, dass ich mit dieser Methode die Bootstraping-Funktionen von Django verwenden kann, um eine Testdatenbank mit dem richtigen Inhalt für jeden Test einzurichten. Und ja, es könnte mit den anderen Antworten kombiniert werden, um das Beste aus beiden Welten zu erhalten.
Emil Stenström

6

Die Antwort von @Pykler ist großartig, aber die Knotenanforderung ist veraltet. Die Kommentare in dieser Antwort deuten auf die einfachere Antwort hin, die ich hier eingefügt habe, um anderen Zeit zu sparen:

  1. Installieren Sie PhantomJS

    Wie @ Vivin-Paliath betont, handelt es sich um ein eigenständiges Projekt, das nicht Teil von Node ist.

    Mac:

    brew install phantomjs

    Ubuntu:

    sudo apt-get install phantomjs

    etc

  2. Richten Sie eine ein virtualenv(falls Sie dies noch nicht getan haben):

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

    Wenn Ihr Computer sowohl über Python 2 als auch über Python 3 verfügt, müssen Sie möglicherweise ausführen virtualenv-3.6 mypyoder ähnliches.

  3. Selen installieren:

    pip install selenium
  4. Versuchen Sie einen einfachen Test, wie diesen aus den Dokumenten entlehnt :

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

Wie installiere ich PhantomJSunter Windows? Es scheint nicht mit pipBefehl zu funktionieren .
MD. Khairul Basar

1
Pip ist ein Python-Paket-Installationsprogramm, daher funktioniert es mit Selen, das als Python-Paket verfügbar ist. PhantomJS ist kein Python-Paket und funktioniert daher nicht mit pip. Ich habe schnell nach "PhantomJS install windows" gesucht und es gibt gute Treffer.
Andrew E

5

das ist was ich tue, python3.3. Ich habe große Listen von Websites verarbeitet, daher war es wichtig, dass das Zeitlimit nicht eingehalten wurde, damit der Job die gesamte Liste durchlaufen konnte.

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

Danke, ich konnte es ändern, um es für meinen Zweck zu schmecken.
iChux

5

Wenn Sie Anaconda verwenden, installieren Sie mit:

conda install PhantomJS

in Ihrem Skript:

from selenium import webdriver
driver=webdriver.PhantomJS()

funktioniert perfekt.


Ab sofort enthalten Standardkanäle kein PhantomJS für Linux64
Eugene Pakhomov

Verdammt, ich liebe Conda <3, das war so einfach. Ich bin auf Osx.
O.rka

1

Falls Sie verwenden Buildout , können Sie einfach die Installationsprozesse automatisieren , dass Pykler das beschreibt die Verwendung von gp.recipe.node Rezept.

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

Dieser Teil installiert node.js als Binärdatei (zumindest auf meinem System) und verwendet dann npm, um PhantomJS zu installieren. Schließlich wird ein Einstiegspunkt erstellt bin/phantomjs, mit dem Sie den PhantomJS-Webdriver aufrufen können. (Um Selenium zu installieren, müssen Sie es in Ihren Ei-Anforderungen oder in der Buildout-Konfiguration angeben.)

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

1
Eine andere Möglichkeit, den Installationsprozess mit dem Buildout zu automatisieren, ist die Verwendung gp.recipe.phantomjs, die konfiguriert phantomjsundcasperjs
gakhov
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.