C'è un modo per usare PhantomJS in Python?


203

Voglio usare PhantomJS in Python . Ho cercato su Google questo problema ma non sono riuscito a trovare soluzioni adeguate.

Trovo che os.popen() possa essere una buona scelta. Ma non ho potuto passare alcuni argomenti ad esso.

L'uso subprocess.Popen()potrebbe essere una soluzione adeguata per ora. Voglio sapere se esiste una soluzione migliore o meno.

C'è un modo per usare PhantomJS in Python?


La mia risposta qui sotto ti dice come farlo. Basta guardare la tua domanda e questo è esattamente ciò che fa il selenio, subprocess.popenma con alcune funzionalità estese per rendere l'api senza soluzione di continuità.
Pykler,

@flyer: probabilmente dovresti considerare di cambiare la risposta accettata, vedi sotto. Grazie.
dotancohen,

Risposte:


373

Il modo più semplice di usare PhantomJS in Python è tramite Selenium. Il metodo di installazione più semplice è

  1. Installa NodeJS
  2. Utilizzando il gestore pacchetti di Node installa phantomjs: npm -g install phantomjs-prebuilt
  3. installa selenio (nel tuo virtualenv, se lo stai usando)

Dopo l'installazione, è possibile utilizzare Phantom semplice come:

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

Se la variabile di ambiente del percorso di sistema non è impostata correttamente, è necessario specificare il percorso esatto come argomento per webdriver.PhantomJS(). Sostituisci questo:

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

... con il seguente:

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

Riferimenti:


40
Funzionava magnificamente e probabilmente mi ha fatto risparmiare giorni. Grazie. Se uno vuole tornare indietro alla pagina intera come sorgente, lo è driver.page_source.
scharfmn,

4
Funziona magnificamente e sono piacevolmente sorpreso perché phantomjs.org/faq.html dice "non un modulo Node.js", ma il wrapper npm su npmjs.org/package/phantomjs lo fa comportare a questo scopo. Nel mio caso volevo farlo: bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")e ... ha funzionato!
MarkHu,

8
Sono d'accordo sul fatto che Ghost abbia dipendenze pazze e in realtà non sono riuscito a metterlo in funzione anche dopo aver installato milioni di librerie correlate a X11. Ghost è una storia dell'orrore.
Pykler,

5
@phabtar Devi passare il percorso a phantomjs come primo argomento a PhantomJS ... o correggere il tuo syspath di Windows per poter vedere phantomjs.
Pykler,

2
Domanda stupida: perché devo installare node-js? non c'è altro modo per ottenere pahantomJs?
Eildosa,

80

PhantomJS ha recentemente abbandonato del tutto il supporto Python . Tuttavia, PhantomJS ora incorpora Ghost Driver .

Dal momento che un nuovo progetto ha intensificato per riempire il vuoto: ghost.py. Probabilmente vorrai usarlo invece:

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
Anche se il supporto è caduto, ho scoperto che installare npm (gestore pacchetti nodo) e usarlo per installare gli ultimi phantomjs (con supporto webdriver) e installare selenio in python ... molto più facile che cercare di far funzionare correttamente PyQT o PySide. La cosa bella di Phantom è davvero senza testa e non richiede librerie correlate a UI / X11 per funzionare.
Pykler,

12
Di seguito ho aggiunto una risposta che spiega la mia soluzione preferita dopo aver provato a usare ghost.py e odiare la mia vita
Pykler

8
"Odiare la mia vita" di Pykler non è un eufemismo. Se qualcuno cambiasse la "risposta corretta" per questa domanda in quella di Pykler, avrei risparmiato un giorno di sforzi.
YPCrumble,

2
@YPCrumble: purtroppo solo l'OP può farlo; cambia la risposta accettata.
Martijn Pieters

3
Dopo aver provato diversi approcci questa mattina, la soluzione @Pykler ha funzionato nel modo più fluido.
Andyzinsser,

40

Da quando GhostDriver viene fornito in bundle con PhantomJS, è diventato ancora più conveniente utilizzarlo tramite Selenium.

Ho provato l'installazione Node di PhantomJS, come suggerito da Pykler, ma in pratica l'ho trovata più lenta dell'installazione standalone di PhantomJS. Immagino che l'installazione autonoma non abbia fornito queste funzionalità in precedenza, ma a partire dalla v1.9, lo fa molto.

  1. Installa PhantomJS ( http://phantomjs.org/download.html ) (Se usi Linux, seguire le istruzioni ti aiuterà https://stackoverflow.com/a/14267295/382630 )
  2. Installa Selenium usando pip.

Ora puoi usare così

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

driver.quit()

3
ringraziamenti speciali per aver indicato la risposta SO relativa all'installazione di PhantomJS su Ubuntu, mi ha aiutato.
Dennis Golomazov,

un modo rapido per installare Selenium che ho appena imparato è, su Windows, digitare: C: \ Python34 \ Scripts \ pip.exe installa Selenium.
ntk4,

8

Ecco come testare javascript usando PhantomJS e 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

Esegui test :

manage.py test mobile


Grazie. Ho usato subprocess.Popen per chiamare lo script phantomjs e ha funzionato :)
flyer

Vedi come questo è limitato, giusto? Tutto quello che stai facendo è effettuare una chiamata shell per eseguire phantomjs - non stai effettivamente utilizzando un'interfaccia "corretta" attraverso la quale puoi gestire correttamente le eccezioni, il blocco, ecc.
kamelkev

@kamelkev: vedo come questo sia limitato. Il lato positivo è che questo metodo mi consente di utilizzare le funzionalità di bootstraping di Django per impostare un database di test con il contenuto corretto per ogni test. E sì, potrebbe essere combinato con le altre risposte per ottenere il meglio da entrambi i mondi.
Emil Stenström,

6

La risposta di @Pykler è ottima ma il requisito del nodo è obsoleto. I commenti in quella risposta suggeriscono la risposta più semplice, che ho messo qui per risparmiare tempo agli altri:

  1. Installa PhantomJS

    Come sottolinea @ Vivin-Paliath, è un progetto autonomo, non parte di Node.

    Mac:

    brew install phantomjs

    Ubuntu:

    sudo apt-get install phantomjs

    eccetera

  2. Imposta un virtualenv(se non l'hai già fatto):

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

    Se la tua macchina ha sia Python 2 che 3, potresti aver bisogno di eseguire virtualenv-3.6 mypyo simili.

  3. Installa selenio:

    pip install selenium
  4. Prova un semplice test, come questo preso in prestito dai documenti :

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

Come installare PhantomJSsu Windows? Non sembra funzionare usando il pipcomando.
MD. Khairul Basar

1
Pip è un programma di installazione di pacchetti python, quindi funziona con selenio, che è disponibile come pacchetto python. PhantomJS non è un pacchetto python quindi non funzionerà con pip. Ho fatto un rapido google per "PhantomJS install windows" e ci sono buoni risultati.
Andrew E

5

questo è quello che faccio, python3.3. Stavo elaborando enormi elenchi di siti, quindi il fallimento del timeout era vitale per il lavoro da eseguire attraverso l'intero elenco.

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

Grazie, sono stato in grado di modificarlo a piacere per il mio scopo.
iChux,

5

Se si utilizza Anaconda, installare con:

conda install PhantomJS

nella tua sceneggiatura:

from selenium import webdriver
driver=webdriver.PhantomJS()

funziona perfettamente.


Al momento, i canali predefiniti non contengono PhantomJS per linux64
Eugene Pakhomov,

accidenti, amo conda <3 che è stato così facile. sono su osx.
O.rka,

1

Nel caso in cui si utilizzi Buildout , è possibile automatizzare facilmente i processi di installazione descritti da Pykler utilizzando la ricetta gp.recipe.node .

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

Quella parte installa node.js come binario (almeno sul mio sistema) e quindi utilizza npm per installare PhantomJS. Alla fine crea un punto di ingresso bin/phantomjs, con il quale è possibile chiamare il webdriver PhantomJS. (Per installare Selenium, è necessario specificarlo nei requisiti dell'uovo o nella configurazione Buildout.)

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

1
un altro modo per automatizzare il processo di installazione con buildout è solo l'uso gp.recipe.phantomjs, che configura phantomjsecasperjs
gakhov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.