2011-11-27 171 views
27

Estoy trabajando en un proyecto de raspado web. Uno de los sitios web con los que estoy trabajando tiene los datos provenientes de Javascript.¿Cómo llamo a una función Javascript desde Python?

Hubo una sugerencia en one of my earlier questions que puedo llamar directamente al Javascript desde Python, pero no estoy seguro de cómo lograr esto.

Por ejemplo: Si una función de JavaScript se define como: add_2(var,var2)

¿Cómo voy a llamar a esa función JavaScript desde Python?

+1

Si es algo que sabe y puede simular fácilmente, puede ser más fácil de analizar e interpretar por sí mismo. De lo contrario, podría terminar teniendo que unirse a un motor de JavaScript. –

Respuesta

9

Encuentra un intérprete de JavaScript que tenga enlaces de Python. (Prueba Rhino? V8? SeaMonkey?). Cuando hayas encontrado uno, debería venir con ejemplos de cómo usarlo desde python.

Python, sin embargo, no incluye un intérprete de JavaScript .

+4

Debería echar un vistazo a [pyv8] (http://code.google.com/p/pyv8/) que ofrece un contenedor de Python para el motor V8 de Google. [Este] (http://devzone.zend.com/1480/using-javascript-in-php-with-pecl-and-spidermonkey/) contiene información sobre el uso de Python con SpiderMonkey. Espero que esto ayude. – Codahk

+3

Si desea admitir más de un motor de JavaScript, debe echar un vistazo a [PyExecJS] (https://pypi.python.org/pypi/PyExecJS) – Wienczny

5

Para interactuar con JavaScript desde Python utilizo webkit, que es el procesador de navegador detrás de Chrome y Safari. Hay Python bindings to webkit through Qt. En particular, hay una función para ejecutar JavaScript llamada evaluateJavaScript().

Aquí hay un completo example to execute JavaScript and extract the final HTML.

+0

Enlace roto. Siempre estoy usando esta solución hasta ahora con un módulo que facilita la interacción con PyQT4 llamado Spynner – c24b

+0

Gracias por la información de arriba - enlace fijo – hoju

2

Eventualmente puede obtener el JavaScript de la página y ejecutarlo a través de algún intérprete (como v8 o Rhino). Sin embargo, puede obtener un buen resultado de una manera mucho más fácil mediante el uso de algunas herramientas de prueba funcionales, como Selenium o Splinter. Estas soluciones inician un navegador y cargan la página de manera efectiva, puede ser lenta pero asegura que el contenido esperado del navegador esté disponible.

Por ejemplo, considere el documento 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> 

El siguiente script utilizará astilla. Astilla lanzará Firefox y después de la carga completa de la página que va a obtener el contenido añadido a un div por JavaScript:

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() 

el resultado será el contenido impreso en la salida estándar.

+0

El selenio es demasiado pesado, por otro lado no sabía astillas. Usado para spynner (en la parte superior de PyQT4 + autopy) – c24b

3

Una alternativa interesante que descubrí recientemente es el módulo Python bond, que se puede usar para comunicarse con un proceso NodeJs (motor v8).

uso sería muy similar a las consolidaciones pyv8, pero se puede directamente utilizar cualquier biblioteca nodejs sin modificaciones, lo cual es un punto de venta importante para mí.

Su código Python se vería así:

val = js.call('add2', var1, var2) 

o incluso:

add2 = js.callable('add2') 
val = add2(var1, var2) 

las funciones de llamada, aunque sin duda es más lento que pyv8, por lo que depende en gran medida de sus necesidades. Si necesita usar un paquete npm que hace mucho trabajo pesado, bond es excelente. Incluso puede tener más procesos nodejs ejecutándose en paralelo.

Pero si solo necesita llamar a un conjunto de funciones JS (por ejemplo, para tener las mismas funciones de validación entre el navegador/back-end), pyv8 será mucho más rápido.

0

Hice un completo desglose de los diferentes métodos recientemente.

PyQt4 Node.js/zombie.js PhantomJS

PhantomJS era las manos ganadoras abajo, muy sencillo con una gran cantidad de ejemplos.

+1

Puede mejorar esta respuesta agregando un fragmento de código que responda la pregunta. –

0

Puede llamar al nodo a través de 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

Incluya el fragmento de código como parte de su respuesta. –

Cuestiones relacionadas