Có cách nào để sử dụng PhantomJS trong Python không?


203

Tôi muốn sử dụng PhantomJS trong Python . Tôi đã giải quyết vấn đề này nhưng không thể tìm ra giải pháp thích hợp.

Tôi thấy os.popen() có thể là một lựa chọn tốt. Nhưng tôi không thể truyền một số lý lẽ cho nó.

Sử dụng subprocess.Popen()có thể là một giải pháp thích hợp cho bây giờ. Tôi muốn biết liệu có một giải pháp tốt hơn hay không.

Có cách nào để sử dụng PhantomJS trong Python không?


Câu trả lời của tôi dưới đây cho bạn biết làm thế nào để làm điều đó. Chỉ cần nhìn vào câu hỏi của bạn và thực sự đó chính xác là những gì Selenium làm, subprocess.popennhưng với một số tính năng mở rộng để làm cho api liền mạch.
Pykler 20/03/2015

@flyer: Có lẽ bạn nên xem xét thay đổi câu trả lời được chấp nhận, xem bên dưới. Cảm ơn bạn.
dotancohen

Câu trả lời:


373

Cách dễ nhất để sử dụng PhantomJS trong python là thông qua Selenium. Phương pháp cài đặt đơn giản nhất là

  1. Cài đặt NodeJS
  2. Sử dụng trình quản lý gói của Node cài đặt ph Phantomjs: npm -g install phantomjs-prebuilt
  3. cài đặt selenium (trong virtualenv của bạn, nếu bạn đang sử dụng)

Sau khi cài đặt, bạn có thể sử dụng ph Phantom đơn giản như:

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

Nếu biến môi trường đường dẫn hệ thống của bạn không được đặt chính xác, bạn sẽ cần chỉ định đường dẫn chính xác làm đối số webdriver.PhantomJS(). Thay thế này:

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

... với những điều sau đây:

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

Người giới thiệu:


40
Điều này làm việc rất đẹp, và có lẽ đã giúp tôi tiết kiệm nhiều ngày. Cảm ơn bạn. Nếu ai đó muốn toàn bộ trang được kết xuất lại dưới dạng nguồn, thì đó là driver.page_source.
scharfmn

4
Điều này hoạt động rất tốt và tôi rất ngạc nhiên vì ph Phantomjs.org/faq.html nói "không phải mô-đun Node.js" - hãy thêm trình bao bọc npm tại npmjs.org/package/ph Phantomjs làm cho nó hoạt động cho mục đích này. Trong trường hợp của tôi, tôi muốn làm điều này: bodyStr= driver.find_element_by_tag_name("body").get_attribute("innerHTML")và ... nó đã hoạt động!
MarkHu

8
Tôi đồng ý rằng ghost có sự phụ thuộc điên rồ và tôi thực sự đã thất bại trong việc cài đặt nó và chạy ngay cả sau khi cài đặt hàng triệu thư viện liên quan đến X11. Ghost là một câu chuyện kinh dị.
Pykler

5
@phabtar Bạn cần chuyển đường dẫn đến ph Phantomjs làm đối số đầu tiên cho PhantomJS ... hoặc sửa lỗi cửa sổ của bạn để có thể nhìn thấy ph Phantomjs.
Pykler

2
Câu hỏi ngớ ngẩn: tại sao tôi phải cài đặt nút-js? không có cách nào khác để có được pah PhantomJs?
Eildosa

80

PhantomJS gần đây đã bỏ hỗ trợ Python hoàn toàn. Tuy nhiên, PhantomJS hiện nhúng Ghost Driver .

Một dự án mới đã bước lên để lấp đầy khoảng trống : ghost.py. Bạn có thể muốn sử dụng thay thế:

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
Mặc dù đã bỏ hỗ trợ, tôi thấy rằng việc cài đặt npm (trình quản lý gói nút) và sử dụng nó để cài đặt ph Phantomjs mới nhất (có hỗ trợ webdo) và cài đặt selenium trong python ... cách dễ dàng hơn là cố gắng để PyQT hoặc PySide hoạt động chính xác. Điều tuyệt vời về ảo là nó thực sự không đầu và không yêu cầu các lib liên quan đến UI / X11 để hoạt động.
Pykler

12
Tôi đã thêm một câu trả lời bên dưới để giải thích giải pháp ưa thích của mình sau khi thử sử dụng ghost.py và ghét cuộc sống của tôi
Pykler

8
"Ghét cuộc sống của tôi" của Pykler không phải là một cách nói nhẹ nhàng. Nếu ai đó thay đổi "câu trả lời đúng" cho câu hỏi này thành Pykler, tôi sẽ tiết kiệm được một ngày.
YPCrumble

2
@YPCrumble: thật không may, chỉ OP mới có thể làm điều đó; thay đổi câu trả lời được chấp nhận
Martijn Pieters

3
Sau khi thử một loạt các cách tiếp cận khác nhau sáng nay, giải pháp @Pykler đã kết thúc hoạt động trơn tru nhất.
andyzinsser

40

Bây giờ kể từ khi GhostDriver đi kèm với PhantomJS, việc sử dụng nó thông qua Selenium trở nên thuận tiện hơn nữa.

Tôi đã thử cài đặt Node của PhantomJS, theo đề xuất của Pykler, nhưng trong thực tế tôi thấy nó chậm hơn so với cài đặt độc lập của PhantomJS. Tôi đoán cài đặt độc lập đã không cung cấp các tính năng này sớm hơn, nhưng kể từ v1.9, nó rất giống như vậy.

  1. Cài đặt PhantomJS ( http ://ph Phantomjs.org/doad.html ) (Nếu bạn đang dùng Linux, các hướng dẫn sau sẽ giúp https://stackoverflow.com/a/14267295/382630 )
  2. Cài đặt Selenium bằng pip.

Bây giờ bạn có thể sử dụng như thế này

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

driver.quit()

3
cảm ơn đặc biệt vì đã chỉ ra câu trả lời SO liên quan đến cài đặt PhantomJS trên Ubuntu, nó đã giúp tôi.
Dennis Golomazov

Một cách nhanh chóng để cài đặt Selenium mà tôi vừa học là, trên Windows, gõ: C: \ Python34 \ Sc scripts \ pip.exe cài đặt Selenium.
ntk4

8

Đây là cách tôi kiểm tra javascript bằng PhantomJS và Django:

di động / 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);
});

điện thoại di động / 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

Chạy thử nghiệm :

manage.py test mobile


Cảm ơn. Tôi đã từng subprocess.Popen gọi kịch bản phantomjs và nó làm việc :)
tờ

Bạn thấy thế nào là hạn chế phải không? Tất cả những gì bạn đang làm là thực hiện một cuộc gọi shell để thực thi ph Phantomjs - bạn không thực sự sử dụng giao diện "phù hợp" mà qua đó bạn có thể xử lý các trường hợp ngoại lệ, chặn, v.v.
kamelkev

@kamelkev: Tôi thấy điều này bị hạn chế. Ưu điểm là phương pháp này cho phép tôi sử dụng các tính năng bootstraping của Django để thiết lập cơ sở dữ liệu thử nghiệm với nội dung chính xác cho mỗi thử nghiệm. Và vâng, nó có thể được kết hợp với các câu trả lời khác để có được điều tốt nhất của cả hai thế giới.
Emil Stenström

6

Câu trả lời của @Pykler rất hay nhưng yêu cầu của Node đã lỗi thời. Các ý kiến ​​trong câu trả lời đó cho thấy câu trả lời đơn giản hơn mà tôi đã đặt ở đây để tiết kiệm thời gian cho người khác:

  1. Cài đặt PhantomJS

    Như @ Vivin-Paliath chỉ ra, đó là một dự án độc lập, không phải là một phần của Node.

    Mac:

    brew install phantomjs

    Ubuntu:

    sudo apt-get install phantomjs

    Vân vân

  2. Thiết lập một virtualenv(nếu bạn chưa có):

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

    Nếu máy của bạn có cả Python 2 và 3, bạn có thể cần chạy virtualenv-3.6 mypyhoặc tương tự.

  3. Cài đặt selen:

    pip install selenium
  4. Hãy thử một bài kiểm tra đơn giản, như thế này mượn từ các tài liệu :

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

Làm thế nào để cài đặt PhantomJStrên windows? Nó dường như không hoạt động bằng cách sử dụng piplệnh.
MD. Khairul Basar

1
Pip là một trình cài đặt gói python, vì vậy nó hoạt động với selenium, có sẵn dưới dạng gói python. PhantomJS không phải là gói python nên sẽ không hoạt động với pip. Tôi đã nhanh chóng tìm kiếm "PhantomJS cài đặt windows" và có những lượt truy cập tốt.
Andrew E

5

đây là những gì tôi làm, python3.3. Tôi đã xử lý danh sách lớn các trang web, vì vậy việc không có thời gian chờ là rất quan trọng để công việc chạy qua toàn bộ danh sách.

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

Cảm ơn, tôi đã có thể thay đổi nó để nếm thử cho mục đích của tôi.
iChux

5

Nếu sử dụng Anaconda, hãy cài đặt với:

conda install PhantomJS

trong kịch bản của bạn:

from selenium import webdriver
driver=webdriver.PhantomJS()

hoạt động hoàn hảo.


Đến bây giờ, các kênh mặc định không chứa PhantomJS cho linux64
Eugene Pakhomov

chết tiệt, tôi yêu conda <3 thật dễ dàng Tôi đang trên osx.
O.rka

1

Trong trường hợp bạn đang sử dụng Buildout , bạn có thể dễ dàng tự động hóa các quy trình cài đặt mà Pykler mô tả bằng cách sử dụng công thức gp.recipe.node .

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

Phần đó cài đặt node.js dưới dạng nhị phân (ít nhất là trên hệ thống của tôi) và sau đó sử dụng npm để cài đặt PhantomJS. Cuối cùng, nó tạo ra một điểm vào bin/phantomjsmà bạn có thể gọi cho webJ của PhantomJS. (Để cài đặt Selenium, bạn cần chỉ định nó trong yêu cầu trứng của bạn hoặc trong cấu hình Buildout.)

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

1
một cách khác để tự động hóa quá trình cài đặt với bản dựng, nó chỉ sử dụng gp.recipe.phantomjs, đó là cấu hình phantomjscasperjs
gakhov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.