L'exécution de Javascript à partir de Python
j'ai des pages Web HTML que j'utilise avec xpath. etree.tostring
d'un certain noeud me donne cette chaîne:
<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>
j'ai juste besoin de la sortie de escramble_758()
. Je peux écrire un regex pour comprendre tout ça, mais je veux que mon code reste ordonné. Quelle est la meilleure alternative?
je suis en train de feuilleter les bibliothèques suivantes, mais je n'ai pas vu de solution exacte. La plupart d'entre eux essaient d'imiter navigateur, de faire des choses escargot lent.
- http://code.google.com/p/python-spidermonkey/ (dit clairement:
it's not yet possible to call a function defined in Javascript
) - http://code.google.com/p/webscraping/ (ne pas voir quoi que ce soit pour Javascript, j'ai peut-être mal)
- http://pypi.python.org/pypi/selenium (Imitant navigateur)
Edit: Un exemple sera grande.. (barebones)
4 réponses
en utilisant PyV8, je peux le faire. Cependant, je dois remplacer document.write
return
parce qu'il n'y a pas de DOM et donc pas de 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 "))
Ou vous pouvez créer une maquette d'objet de document
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
vous pouvez également utiliser Js2Py qui est écrit en python pur et qui est capable d'exécuter et de traduire javascript en python. Prend en charge pratiquement tout JavaScript même les étiquettes, les getters, les setters et d'autres caractéristiques rarement utilisées.
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
Pour l'installer:
pip install js2py
une solution de plus car PyV8 semble être non maintenu et dépend de l'ancienne version de libv8.
PyMiniRacer c'est une enveloppe autour du moteur v8 et il fonctionne avec la nouvelle version et est activement maintenu.
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")
Et oui, vous devez remplacer document.write
return
comme d'autres ont suggéré
Vous pouvez également utiliser le contexte js2py pour exécuter votre fonction js et obtenir la sortie du document.ecrire avec un objet de document fictif:
import js2py
js = """
var output;
document = {
write: function(value){
output = value;
}
}
""" + your_script
context = js2py.EvalJs()
context.execute(js)
print(context.output)