Apakah ada cara untuk menggunakan PhantomJS dengan Python?

203

Saya ingin menggunakan PhantomJS dengan Python . Saya mencari masalah ini di Google tetapi tidak menemukan solusi yang tepat.

Saya menemukan os.popen() mungkin pilihan yang bagus. Tapi saya tidak bisa memberikan beberapa argumen padanya.

Menggunakan subprocess.Popen()mungkin merupakan solusi yang tepat untuk saat ini. Saya ingin tahu apakah ada solusi yang lebih baik atau tidak.

Apakah ada cara untuk menggunakan PhantomJS dengan Python?

pamflet
sumber
Jawaban saya di bawah ini memberi tahu Anda cara melakukannya. Hanya dengan melihat pertanyaan Anda dan sebenarnya itulah yang dilakukan Selenium, subprocess.popentetapi dengan beberapa fitur tambahan untuk membuat apinya mulus.
Pykler
@flyer: Anda mungkin harus mempertimbangkan untuk mengubah jawaban yang diterima, lihat di bawah. Terima kasih.
dotancohen

Jawaban:

373

Cara termudah untuk menggunakan PhantomJS dalam python adalah melalui Selenium. Metode instalasi yang paling sederhana adalah

  1. Instal NodeJS
  2. Menggunakan manajer paket Node menginstal phantomjs: npm -g install phantomjs-prebuilt
  3. instal selenium (di virtualenv Anda, jika Anda menggunakannya)

Setelah instalasi, Anda dapat menggunakan hantu sesederhana:

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

Jika variabel lingkungan jalur sistem Anda tidak disetel dengan benar, Anda harus menentukan jalur yang tepat sebagai argumen webdriver.PhantomJS(). Ganti ini:

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

... dengan yang berikut ini:

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

Referensi:

Pykler
sumber
40
Ini bekerja dengan indah, dan mungkin menyelamatkan saya berhari-hari. Terima kasih. Jika seseorang ingin seluruh halaman yang dirender kembali sebagai sumber, itu driver.page_source.
scharfmn
4
Ini berfungsi dengan baik, dan saya terkejut karena phantomjs.org/faq.html mengatakan "bukan modul Node.js" - tapi pembungkus npm di npmjs.org/package/phantomjs membuatnya berperilaku untuk tujuan ini. Dalam kasus saya, saya ingin melakukan ini: bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")dan ... itu berhasil!
MarkHu
8
Saya setuju bahwa hantu memiliki dependensi gila, dan saya benar-benar gagal untuk menjalankannya dan berjalan bahkan setelah menginstal jutaan perpustakaan terkait X11. Hantu adalah kisah horor.
Pykler
5
@ phabtar Anda harus meneruskan path ke phantomjs sebagai argumen pertama ke PhantomJS ... atau memperbaiki syspath windows Anda untuk dapat melihat phantomjs.
Pykler
2
Pertanyaan bodoh: mengapa saya harus menginstal node-js? Apakah tidak ada cara lain untuk mendapatkan pahantom?
Eildosa
80

PhantomJS baru-baru ini menjatuhkan dukungan Python sama sekali. Namun, PhantomJS sekarang menyematkan Driver Hantu .

Karena A proyek baru telah melangkah untuk mengisi kekosongan: ghost.py. Anda mungkin ingin menggunakannya:

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
Martijn Pieters
sumber
21
Meskipun dukungan dibatalkan, saya menemukan bahwa menginstal npm (manajer paket node) dan menggunakannya untuk menginstal phantomjs terbaru (dengan dukungan webdriver) dan menginstal selenium dalam python ... jauh lebih mudah daripada mencoba membuat PyQT atau PySide berfungsi dengan baik. Apa yang baik tentang hantu itu benar-benar tanpa kepala dan tidak memerlukan lib terkait UI / X11 untuk bekerja.
Pykler
12
Saya menambahkan jawaban di bawah ini untuk menjelaskan solusi pilihan saya setelah mencoba menggunakan ghost.py dan membenci hidup saya
Pykler
8
"Membenci hidupku" Pykler bukanlah pernyataan yang meremehkan. Jika seseorang akan mengubah "jawaban yang benar" untuk pertanyaan ini ke Pykler, saya akan menghemat upaya sehari.
YPCrumble
2
@YPCrumble: sayangnya, hanya OP yang bisa melakukannya; ubah jawaban yang diterima.
Martijn Pieters
3
Setelah mencoba banyak pendekatan berbeda pagi ini, solusi @Pykler akhirnya bekerja paling lancar.
andyzinsser
40

Sekarang karena GhostDriver dibundel dengan PhantomJS, bahkan menjadi lebih nyaman untuk menggunakannya melalui Selenium.

Saya mencoba instalasi Node dari PhantomJS, seperti yang disarankan oleh Pykler, tetapi dalam praktiknya saya menemukan itu lebih lambat daripada instalasi mandiri PhantomJS. Saya kira instalasi mandiri tidak menyediakan fitur-fitur ini sebelumnya, tetapi pada v1.9, sangat banyak yang melakukannya.

  1. Instal PhantomJS ( http://phantomjs.org/download.html ) (Jika Anda menggunakan Linux, petunjuk berikut akan membantu https://stackoverflow.com/a/14267295/382630 )
  2. Instal Selenium menggunakan pip.

Sekarang Anda bisa menggunakan seperti ini

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

driver.quit()
Pankaj
sumber
3
terima kasih khusus untuk menunjuk ke jawaban SO mengenai instalasi PhantomJS di Ubuntu, itu membantu saya.
Dennis Golomazov
cara cepat untuk menginstal Selenium yang baru saya pelajari adalah, pada Windows, ketik: C: \ Python34 \ Scripts \ pip.exe instal Selenium.
ntk4
8

Inilah cara saya menguji javascript menggunakan PhantomJS dan 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);
});

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

Jalankan tes :

manage.py test mobile

Emil Stenström
sumber
Terima kasih. Saya menggunakan subprocess.Popen untuk memanggil skrip phantomjs dan berhasil :)
flyer
Anda melihat bagaimana ini terbatas bukan? Yang Anda lakukan hanyalah membuat panggilan shell untuk mengeksekusi phantomjs - Anda sebenarnya tidak menggunakan antarmuka yang "tepat" di mana Anda dapat menangani pengecualian, pemblokiran, dll.
kamelkev
@kelkev: Saya melihat bagaimana ini terbatas. Sisi positifnya adalah metode ini memungkinkan saya untuk menggunakan fitur bootstraping Django untuk membuat database uji dengan konten yang benar untuk setiap tes. Dan ya, itu bisa dikombinasikan dengan jawaban lain untuk mendapatkan yang terbaik dari kedua dunia.
Emil Stenström
6

The jawaban dengan @Pykler besar tetapi kebutuhan Node sudah usang. Komentar dalam jawaban itu menyarankan jawaban yang lebih sederhana, yang saya taruh di sini untuk menghemat waktu orang lain:

  1. Instal PhantomJS

    Seperti yang ditunjukkan oleh @ Vivin-Paliath, ini adalah proyek mandiri, bukan bagian dari Node.

    Mac:

    brew install phantomjs

    Ubuntu:

    sudo apt-get install phantomjs

    dll

  2. Siapkan virtualenv(jika Anda belum):

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

    Jika mesin Anda memiliki Python 2 dan 3, Anda mungkin harus menjalankan virtualenv-3.6 mypyatau serupa.

  3. Instal selenium:

    pip install selenium
  4. Coba tes sederhana, seperti ini yang dipinjam dari dokumen :

    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()
Andrew E
sumber
Bagaimana cara menginstal PhantomJSdi windows? Tampaknya tidak berfungsi menggunakan pipperintah.
MD. Khairul Basar
1
Pip adalah penginstal paket python, sehingga ia bekerja dengan selenium, yang tersedia sebagai paket python. PhantomJS bukan paket python jadi tidak akan berfungsi dengan pip. Saya melakukan google cepat untuk "PhantomJS install windows" dan ada hits yang bagus.
Andrew E
5

ini yang saya lakukan, python3.3. Saya sedang memproses daftar situs yang sangat besar, sehingga gagal pada batas waktu sangat penting bagi pekerjaan untuk menelusuri seluruh daftar.

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
sumber
Terima kasih, saya bisa mengubahnya sesuai selera untuk tujuan saya.
iChux
5

Jika menggunakan Anaconda, instal dengan:

conda install PhantomJS

dalam skrip Anda:

from selenium import webdriver
driver=webdriver.PhantomJS()

bekerja dengan sempurna.

clg4
sumber
Sampai sekarang, saluran standar tidak mengandung PhantomJS untuk linux64
Eugene Pakhomov
sial, aku suka konda <3 itu sangat mudah. saya di osx.
O.rka
1

Jika Anda menggunakan Buildout , Anda dapat dengan mudah mengotomatiskan proses instalasi yang dijelaskan Pykler menggunakan resep gp.recipe.node .

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

Bagian itu menginstal node.js sebagai biner (setidaknya di sistem saya) dan kemudian menggunakan npm untuk menginstal PhantomJS. Akhirnya ia menciptakan titik masuk bin/phantomjs, yang bisa Anda sebut sebagai webdriver PhantomJS. (Untuk menginstal Selenium, Anda perlu menentukannya dalam persyaratan telur Anda atau dalam konfigurasi Buildout.)

driver = webdriver.PhantomJS('bin/phantomjs')
Denis Drescher
sumber
1
cara lain untuk mengotomatiskan proses instalasi dengan buildout, gunakan saja gp.recipe.phantomjs, yang mengkonfigurasi phantomjsdancasperjs
gakhov