2013-04-01 65 views
27

我想在我的node.js腳本中使用phantomjs。有一個phantomjs-node庫..但不幸的是,作者用這種怪異的咖啡腳本代碼來解釋他在做什麼:phantomjs可以使用node.js嗎?

phantom = require 'phantom' 

phantom.create (ph) -> 
    ph.createPage (page) -> 
    page.open "http://www.google.com", (status) -> 
     console.log "opened google? ", status 
     page.evaluate (-> document.title), (result) -> 
     console.log 'Page title is ' + result 
     ph.exit() 

現在,如果我要使用phantomjs直接使用JavaScript,它會看起來像this

var page = require('webpage').create(); 
page.open(url, function (status) { 
    var title = page.evaluate(function() { 
     return document.title; 
    }); 
    console.log('Page title is ' + title); 
}); 

所以基本上我試圖寫上去的代碼上面普通的JavaScript的第一個片段的當量(通過讀取咖啡腳本documentation ..這是我做過什麼:

// file name: phantomTest.js 

var phantom = require('phantom'); 

phantom.create(function(ph) { 
    ph.createPage(function(page) { 
     page.open('http://www.google.com', function(status) { 
      console.log('opened google?', status); 
      var title = page.evaluate(function() { 
       return document.title; 
      }); 
      console.log('page title is ' + title);    
     }); 
    }); 
    ph.exit(); 
}); 

不幸的是它不工作!如果我在shell中運行

node phantomTest.js 

,沒有任何反應..沒有回報和進程不會停止..任何想法?

更新:

我剛纔讀這在phantomjs faq

問:爲什麼不PhantomJS寫爲Node.js的模塊?

答:答案很簡單:「一個人不能事奉兩個主。」

更長的解釋如下。

截至目前,這在技術上非常具有挑戰性。

每個Node.js的模塊本質上是「從屬」到的Node.js, 即,「主」的核心。在目前的狀態下,PhantomJS(及其包含的 WebKit)需要完全控制(在同步問題中)所有事件:事件循環,網絡堆棧和JavaScript執行。

如果意圖只是使用在Node.js中運行的腳本 來使用PhantomJS,那麼可以通過啓動PhantomJS進程並與其交互來實現這樣的「鬆散綁定」。

嗯..可這有什麼關係呢?但那整個圖書館都沒有意義!

更新2:

我發現這個代碼在做同樣的事情的web

var phantom = require('phantom'); 
phantom.create(function(ph) { 
    return ph.createPage(function(page) { 
    return page.open("http://www.google.com", function(status) { 
     console.log("opened google? ", status); 
     return page.evaluate((function() { 
     return document.title; 
     }), function(result) { 
     console.log('Page title is ' + result); 
     return ph.exit(); 
     }); 
    }); 
    }); 
}); 

可惜就是不工作或者..同樣的結果!

+3

返回調用一些「愚蠢」,因爲你不知道它是如何工作和/或你不能讓你的情況是工作很粗魯。 –

+2

另外,還有比其他Node.js網橋更受推薦的https://github.com/sheebz/phantom-proxy。人們一直在使用Ruby,PHP和Node.js橋接PhantomJS,並取得了不同的成功。 –

+3

對於我強烈的措辭表示歉意,我會從這個問題中提出來。我還會看看'phantom-proxy' ..在這一天結束時,我的目標是讓事情有效,它是不要貶低別人的努力。 – abbood

回答

38

phantomjs節點不是一個官方支持NPM包phantomjs。相反,它通過創建一個使用websocket作爲節點和幻像之間的IPC通道的Web服務器,在節點和幻像之間實現了一個「噁心的巧妙橋樑」。I'm not making this up

所以我們通過旋轉起來ExpressJS的一個實例,在子進程打開幻影,並在一個特殊的網頁,輪流socket.io消息進入警戒指向它()調用與PhantomJS溝通。那些alert()調用被Phantom拾起,你去了!

所以我不會驚訝,如果phantomjs節點的工作,不工作,失敗默默,或失敗壯觀。我也不希望除phantomjs-node的作者以外的任何人能夠對phantomjs-node進行故障排除。

您的原始問題的答案是phantomjs faq的答案:不。幻影和節點有不可調和的差異。它們都希望完全控制事件循環,網絡堆棧和JS執行等基本底層功能,因此它們不能在同一個進程中合作。

+5

哇,這很討厭!那麼接下來的問題是:用jquery刮動態頁面的最佳方式是什麼? – abbood

+0

@abbood我不認爲這是可能的。你的目標是什麼? –

+1

爲什麼不可能?雖然..我一直認爲我找到了我的[答案](https://github.com/tmpvar/jsdom/)..我一開始就採取不可能的艱難路線,只是爲了找到一個更簡單的解決方案大聲笑..我'你會給你正確的答案獎勵。 – abbood

0

我遇到了同樣的問題,顯然,known issuephantomjs-node和更新版本的nodejs。根據問題中的評論,似乎它在節點0.9.3附近停止工作。因此,在解決問題之前,您必須降級nodejs,或者嘗試使用其他模塊,例如node-phantom或僅使用exec/spawn

1

更改您的代碼這一點,並且將工作:

var phantom = require('phantom'); 
phantom.create(function(ph) { 
    ph.createPage(function(page) { 
    page.open("http://www.google.com", function(status) { 
     console.log("opened google? ", status); 
     page.evaluate((function() { 
     return document.title; 
     }), function(result) { 
     console.log('Page title is ' + result); 
     ph.exit(); 
     }); 
    }); 
    }); 
}); 
9

你也可以給phridge一試。你的榜樣會一直這樣寫的:

var phantom; 

// spawn a new PhantomJS process 
phridge.spawn() 
    .then(function (ph) { 
     phantom = ph; 
     return phantom.openPage("http://www.google.com"); 
    }) 
    .then(function (page) { 
     return page.run(function() { 
      // this function runs inside PhantomJS with this bound to a webpage instance 
      return this.title; 
     }); 
    }) 
    .then(function (title) { 
     console.log('Page title is ' + title); 
     // terminates the process cleanly 
     phantom.dispose(); 
    }); 
1

你可以只溝PhantomJS像我一樣,因爲它只是太多與這些包裝都不盡如人意疼痛,並與Zombie.js這是非常流行的太去。

9

我現在是phantom-node包的新維護者。它不再使用coffeescript。你可以做類似於

var phantom = require('phantom'); 

phantom.create().then(function(ph) { 
    ph.createPage().then(function(page) { 
    page.open('https://stackoverflow.com/').then(function(status) { 
     console.log(status); 
     page.property('content').then(function(content) { 
     console.log(content); 
     page.close(); 
     ph.exit(); 
     }); 
    }); 
    }); 
}); 

新版本更快更有彈性。它也不再使用websockets。

1

看來,這是工作..

var phantom = require('phantom'); 

phantom.create().then(function(ph) { 
    ph.createPage().then(function(page) { 
    page.open('https://stackoverflow.com/').then(function(status) { 
     console.log(status); 
     page.property('content').then(function(content) { 
     console.log(content); 
     page.close(); 
     ph.exit(); 
     }); 
    }); 
    }); 
}); 

但我想產生一些外部腳本文件的HTML頁面。它無法注入腳本文件。我試着像下面一樣。回調不從線page.injectJs('./jQuery.min.js',function() {

var phantom = require('phantom'); 

    phantom.create().then(function(ph) { 
     ph.createPage().then(function(page) { 
     page.injectJs('./jQuery.min.js', function() { 
      page.property('content').then(function(content) { 
      console.log(content); 
      page.close(); 
      ph.exit(); 
      }); 
     }); 
     }); 
    }); 
相關問題