J'ai des pages Web HTML que j'explore à l'aide de xpath. Le etree.tostring
D'un certain nœud 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 une expression régulière pour comprendre le tout, mais je veux que mon code reste en ordre. Quelle est la meilleure alternative?
Je passe en revue les bibliothèques suivantes, mais je n'ai pas vu de solution exacte. La plupart d'entre eux essaient d'émuler le navigateur, ce qui ralentit les choses.
it's not yet possible to call a function defined in Javascript
)Edit: Un exemple sera génial .. (barebones fera l'affaire)
En utilisant PyV8 , je peux le faire. Cependant, je dois remplacer document.write
avec return
car 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 un faux objet 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 pur python et est capable d'exécuter et de traduire javascript en python. Prend en charge pratiquement tous les libellés JavaScript, getters, setters et autres fonctionnalités 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
Les avantages de Js2Py incluent la portabilité et une intégration extrêmement facile avec python (car essentiellement JavaScript est en cours de traduction en python).
À installer:
pip install js2py
Une autre solution car PyV8 ne semble pas être maintenue et dépend de l'ancienne version de libv8.
PyMiniRacer C'est un wrapper 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
avec return
comme d'autres l'ont suggéré
Vous pouvez utiliser le contexte js2py pour exécuter votre code js et obtenir la sortie de document.write avec un faux objet document:
import js2py
js = """
var output;
document = {
write: function(value){
output = value;
}
}
""" + your_script
context = js2py.EvalJs()
context.execute(js)
print(context.output)