Executing JavaScript from Python

Executing Javascript from Python

Using PyV8, I can do this. However, I have to replace document.write with return because there's no DOM and therefore no 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 "))

Or you could create a mock document object

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

How can I execute JavaScript code from Python?

The module Naked does exactly this. pip install Naked (or install from source if you prefer) and import the library shell functions as follows:

from Naked.toolshed.shell import execute_js, muterun_js

response = muterun_js('file.js')
if response.exitcode == 0:
print(response.stdout)
else:
sys.stderr.write(response.stderr)

For your particular case, with file.js as

var x = 10;
x = 10 - 5;
console.log(x);
function greet() {
console.log("Hello World!");
}
greet()

the output is '5\nHello World!\n', which you can parse as desired.

How to run JavaScript function inside Python code

OK, here is Python code using BeautifulSoup that does what your Javascript does. Basically, if the text in the first <td> tag in each row is the same as the previous row, then we delete this tag an bump the "rowspan" for the previous tag.

from bs4 import BeautifulSoup

dom = BeautifulSoup(open('x.html').read(), 'lxml')
tbl = dom.find('table')
last = None
for row in tbl.find_all('tr'):
this = row.find('td')
if last and this.text == last.text:
this.decompose()
if 'rowspan' not in last:
last['rowspan'] = 1
last['rowspan'] += 1
else:
last = this
print(dom)

Before text:

<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
<tr>
<td>C</td>
<td>E</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
</tr>
</table>

After:

<html><body><table>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td rowspan="2">C</td>
<td>D</td>
</tr>
<tr>

<td>E</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
</tr>
</table>
</body></html>

How do I call a Javascript function from Python?

Find a JavaScript interpreter that has Python bindings. (Try Rhino? V8? SeaMonkey?). When you have found one, it should come with examples of how to use it from python.

Python itself, however, does not include a JavaScript interpreter.

Call Javascript from python

According to https://stackoverflow.com/a/30537286/6353933,

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

Advantages of Js2Py include portability and extremely easy integration with python (since basically JavaScript is being translated to python).

To install:

pip install js2py

Execute Javascript using Selenium in Python

If $ represents jQuery, you would first have to load it into the browser as follows if it has not already been loaded by the current page:

path_to_jquery_js = '/my_scripts/jquery.js' # for example
with open(path_to_jquery_js, 'r') as f:
jquery_js = r.read()
browser.execute_script(jquery_js)

If you do not have jQuery stored locally, then you would have to use something like the requests module from the PyPi repository to fetch it:

import requests

jquery_url = 'https://some_domain/jquery.js' # for example
r = requests.get(jquery_url)
jquery_js = r.text
browser.execute_script(jquery_js

Then you should be able to execute the script as follows:

script = """
var ep_start = $('#episode_page a.active').attr('ep_start');
var ep_end = $('#episode_page a.active').attr('ep_end');
var id = $("input#movie_id").val();
var default_ep = $("input#default_ep").val();
var alias = $("input#alias_anime").val();
loadListEpisode('#episode_page a.active',ep_start,ep_end,id,default_ep,alias);
"""

browser.execute_script(script)

Just make sure loadListEpisode is already defined by other JavaScript that has already been loaded.

This is untested by me for obvious reasons, but give it a shot -- it should work in principle. Let me know how it goes (I am sure you will).



Related Topics



Leave a reply



Submit