2011-11-27 108 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

请将代码片段作为答案的一部分。 –