web-dev-qa-db-ja.com

PythonからJavascriptを実行

Xpathを使用してクロールしているHTML Webページがあります。特定のノードの_etree.tostring_は、次の文字列を提供します。

_<script>
<!--
function escramble_758(){
  var a,b,c
  a='+1 '
  b='84-'
  a+='425-'
  b+='7450'
  c='9'
  document.write(a+c+b)
}
escramble_758()
//-->
</script>
_

escramble_758()の出力が必要です。正規表現を書いて全体を把握することはできますが、コードを整頓しておく必要があります。最良の選択肢は何ですか?

次のライブラリを参照していますが、正確な解決策が見つかりませんでした。それらのほとんどはブラウザをエミュレートしようとしているため、カタツムリが遅くなります。

編集:例は素晴らしいでしょう..(barebonesが行います)

43
jerrymouse

PyV8 を使用して、これを行うことができます。ただし、document.write with returnにはDOMがなく、したがってdocumentもありません。

import PyV8
ctx = PyV8.JSContext()
ctx.enter()

js = """
function escramble_758(){
var a,b,c
a='+1 '
b='84-'
a+='425-'
b+='7450'
c='9'
document.write(a+c+b)
}
escramble_758()
"""

print ctx.eval(js.replace("document.write", "return "))

または、模擬ドキュメントオブジェクトを作成できます

class MockDocument(object):

    def __init__(self):
        self.value = ''

    def write(self, *args):
        self.value += ''.join(str(i) for i in args)


class Global(PyV8.JSClass):
    def __init__(self):
        self.document = MockDocument()

scope = Global()
ctx = PyV8.JSContext(scope)
ctx.enter()
ctx.eval(js)
print scope.document.value
34
Kien Truong

また、純粋なpythonで記述され、javascriptをpythonに実行および変換することができるJs2Pyを使用することもできます。ラベル、ゲッター、セッター、およびその他のめったに使用されない機能を含むJavaScript全体を実質的にサポートします。

import js2py

js = """
function escramble_758(){
var a,b,c
a='+1 '
b='84-'
a+='425-'
b+='7450'
c='9'
document.write(a+c+b)
}
escramble_758()
""".replace("document.write", "return ")

result = js2py.eval_js(js)  # executing JavaScript and converting the result to python string 

Js2Pyの利点には、移植性とpython(基本的にJavaScriptはpythonに変換されているため)との非常に簡単な統合が含まれます。

インストールする:

pip install js2py
40
Piotr Dabkowski

PyV8としてのもう1つのソリューションは、メンテナンスされておらず、古いバージョンのlibv8に依存しているようです。

PyMiniRacer これはv8エンジンのラッパーであり、新しいバージョンで動作し、アクティブに維持されます。

pip install py-mini-racer

from py_mini_racer import py_mini_racer
ctx = py_mini_racer.MiniRacer()
ctx.eval("""
function escramble_758(){
    var a,b,c
    a='+1 '
    b='84-'
    a+='425-'
    b+='7450'
    c='9'
    return a+c+b;
}
""")
ctx.call("escramble_758")

そして、はい、あなたはdocument.writereturnと他の人が提案したように

14
Dienow

Js2pyコンテキストを使用してjsコードを実行し、模擬ドキュメントオブジェクトを使用してdocument.writeから出力を取得できます。

import js2py

js = """
var output;
document = {
    write: function(value){
        output = value;
    }
}
""" + your_script

context = js2py.EvalJs()
context.execute(js)
print(context.output)
1
Mirko