2011-11-27 109 views
27

我正在進行網絡抓取項目。我正在使用的其中一個網站的數據來自Javascript。如何從Python調用Javascript函數?

有一個關於one of my earlier questions的建議,我可以直接從Python調用Javascript,但我不確定如何完成此操作。

例如:如果一個JavaScript函數定義爲:add_2(var,var2)

我怎麼會叫,從Python的JavaScript函數?

+1

如果這是你知道的,很容易模仿的東西,它可能是最簡單的分析和自己的解釋。如果不是,你最終可能需要綁定到JavaScript引擎。 –

回答

9

找到一個具有Python綁定的JavaScript解釋器。 (試試Rhino?V8?SeaMonkey?)。當你找到一個,它應該帶有如何從python使用它的例子。

但是,Python本身不包含JavaScript解釋器

+4

您絕對應該查看[pyv8](http://code.google.com/p/pyv8/),它爲Google的V8引擎提供python包裝。 [This](http://devzone.zend.com/1480/using-javascript-in-php-with-pecl-and-spidermonkey/)包含有關使用Python與SpiderMonkey的信息。希望這可以幫助。 – Codahk

+3

如果你想支持多個JavaScript引擎,你應該看看[PyExecJS](https://pypi.python.org/pypi/PyExecJS) – Wienczny

5

從Python與JavaScript交互我使用webkit,它是Chrome和Safari後面的瀏覽器渲染器。有Python bindings to webkit through Qt。特別是有一個執行JavaScript的函數叫做evaluateJavaScript()

這是一個完整的example to execute JavaScript and extract the final HTML

+0

鏈接斷了!我總是使用這個解決方案,直到現在還有一個模塊可以讓PyQT4與PyQT4更容易的交互,叫做Spynner – c24b

+0

感謝您的支持 - 固定鏈接 – hoju

2

您最終可以從頁面獲取JavaScript並通過某些解釋器(如v8或Rhino)執行它。但是,通過使用一些功能測試工具(如SeleniumSplinter),您可以通過更簡單的方式獲得較好的結果。這些解決方案啓動一個瀏覽器並有效地加載頁面 - 它可能很慢,但可以確保預期的瀏覽器顯示內容可用。

例如,請考慮下面的HTML文檔:

<html> 
    <head> 
     <title>Test</title> 
     <script type="text/javascript"> 
      function addContent(divId) { 
       var div = document.getElementById(divId); 
       div.innerHTML = '<em>My content!</em>'; 
      } 
     </script> 
    </head> 
    <body> 
     <p>The element below will receive content</p> 
     <div id="mydiv" /> 
     <script type="text/javascript">addContent('mydiv')</script> 
    </body> 
</html> 

下面的腳本將使用分裂。斯普林特將推出Firefox和頁面加載完成後,將獲得由JavaScript添加到一個div內容:

from splinter.browser import Browser 
import os.path 

browser = Browser() 
browser.visit('file://' + os.path.realpath('test.html')) 
elements = browser.find_by_css("#mydiv") 
div = elements[0] 
print div.value 

browser.quit() 

其結果將是在標準輸出打印的內容。

+0

硒太重了,我不知道分裂。用於spynner(在PyQT4 + autopy的頂部) – c24b

3

一個有趣的選擇我最近發現是Python bond模塊,其可用於與過程的NodeJS(V8發動機)進行通信。

用法是非常相似的pyv8綁定,但你可以直接使用任何圖書館的NodeJS無需修改,這是一個主要賣點爲我。

Python代碼應該是這樣的:

val = js.call('add2', var1, var2) 

甚至:

add2 = js.callable('add2') 
val = add2(var1, var2) 

調用函數雖然肯定比pyv8慢,所以它在很大程度上取決於你的需求。如果您需要使用npm程序包,那麼很難做到這一點,bond就是了不起。你甚至可以有更多的nodejs進程並行運行。

但是,如果您只需調用一堆JS函數(例如,在瀏覽器/後端之間具有相同的驗證函數),pyv8肯定會快很多。

0

最近對不同方法做了整體分析。

PyQt4的 的node.js/zombie.js phantomjs

Phantomjs是贏家倒手,非常簡單,有很多的例子。

+1

您可以通過添加代碼片段來改進此答案,而不是回答問題。 –

0

你可能會通過Popen調用節點。

My example how to do it

print execute('''function (args) { 
    var result = 0; 
    args.map(function (i) { 
     result += i; 
    }); 
    return result; 
}''', args=[[1, 2, 3, 4, 5]]) 
+1

請將代碼片段作爲答案的一部分。 –