如何从Python调用Javascript函数?

时间:2011-11-27 10:02:44

标签: javascript python web-scraping

我正在开展网络抓取项目。我正在使用的其中一个网站的数据来自Javascript。

one of my earlier questions有一个建议我可以直接从Python调用Javascript,但我不知道如何实现这一点。

例如:如果JavaScript函数定义为:add_2(var,var2)

我如何从Python调用该JavaScript函数?

7 个答案:

答案 0 :(得分:9)

查找具有Python绑定的JavaScript解释器。 (试试Rhino?V8?SeaMonkey?)。当你找到一个时,它应该带有如何在python中使用它的例子。

然而,

Python本身并不包含 JavaScript解释器

答案 1 :(得分:5)

要从Python与JavaScript交互,我使用webkit,这是Chrome和Safari背后的浏览器渲染器。有Python bindings to webkit through Qt。特别是有一个执行名为evaluateJavaScript()的JavaScript的函数。

这是一个完整的example to execute JavaScript and extract the final HTML

答案 2 :(得分:4)

我最近发现的一个有趣的替代方案是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肯定会快得多。

答案 3 :(得分: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>

下面的脚本将使用Splinter。 Splinter将启动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()

结果将是stdout中打印的内容。

答案 4 :(得分:0)

最近对不同方法进行了彻底的破坏。

PyQt4的 的node.js / zombie.js phantomjs

Phantomjs是获胜者,非常直截了当,有很多例子。

答案 5 :(得分: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]])

答案 6 :(得分:0)

嗨,所以一种可能的解决方案是使用 ajax 和flask 在javascript 和python 之间进行通信。您将使用 Flask 运行服务器,然后在浏览器中打开网站。通过这种方式,您可以在通过 python 代码或按钮创建网站时运行 javascript 函数,在本示例中是如何完成的。

HTML 代码:



<html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>


<script>
    function pycall() {
      $.getJSON('/pycall', {content: "content from js"},function(data) {
          alert(data.result);
      });
    }
</script>


<button type="button" onclick="pycall()">click me</button>
 

</html>

Python 代码:

from flask import Flask, jsonify, render_template, request

app = Flask(__name__)


def load_file(file_name):
    data = None
    with open(file_name, 'r') as file:
        data = file.read()
    return data

@app.route('/pycall')
def pycall():
    content = request.args.get('content', 0, type=str)
    
    print("call_received",content)
    return jsonify(result="data from python")

@app.route('/')
def index():
    return load_file("basic.html")



import webbrowser
print("opening localhost")
url = "http://127.0.0.1:5000/"
webbrowser.open(url)
app.run()

python 输出:

call_received content from js

浏览器中的警报:

data from python