creating and executing a Javascript function with Selenium - python

I am trying to create and execute a JavaScript function with Selenium. I am doing it like this:
js_func = """
function blah(a, b, c) {
.
.
.
};
"""
self.selenium.execute_script(js_script)
self.selenium.execute_script("blah", 1,2,3)
I don't get any errors from the first one (creating the function), but the second one gives me:
WebDriverException: Message: u'blah is not defined'
Is what I'm doing valid? How I can tell if the function was successfully created? How can I see the errors (assuming there are errors)?

It's just how Selenium executes JavaScript:
The script fragment provided will be executed as the body of an anonymous function.
In effect, your code is:
(function() {
function blah(a, b, c) {
...
}
})();
(function() {
blah(1, 2, 3);
});
And due to JavaScript's scoping rules, blah doesn't exist outside of that anonymous function. You'll have to make it a global function:
window.blah = function(a, b, c) {
...
}
Or execute both scripts in the same function call.

Related

Pybind11 - Function with unknown number of arguments

I want to get a list of arguments
my current c++ code:
m.def("test", [](std::vector<pybind11::object> args){
return ExecuteFunction("test", args);
});
my current python code:
module.test(["-2382.430176", "-610.183594", "12.673874"])
module.test([])
I want my python code to look like this:
module.test("-2382.430176", "-610.183594", "12.673874")
module.test()
How can I get all arguments passed through Python?
Such generic functions module.test(*args) can be created using pybind11:
void test(py::args args) {
// do something with arg
}
// Binding code
m.def("test", &test);
Or
m.def("test", [](py::args args){
// do something with arg
});
See Accepting *args and **kwargs and the example for more details.
m.def("test", [](const pybind11::args& args){
std::vector<pybind11::object> pyArgs;
for (const auto &arg : args) {
pyArgs.push_back(arg.cast<pybind11::object>());
}
return ExecuteFunction("test", pyArgs);
});
I have to admit I'm not entirely sure what you're trying to do, but here is one idea:
def wrapper(args*)
return module.test(args)
There are other ways of making such a wrapper but this should work if I understand your question correctly.

Running a python script in C# after publishing C# project [duplicate]

I have been working on a problem for a while now which I cannot seem to resolve so I need some help! The problem is that I am writing a program in C# but I require a function from a Python file I created. This in itself is no problem:
...Usual Stuff
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace Program
{
public partial class Form1 : Form
{
Microsoft.Scripting.Hosting.ScriptEngine py;
Microsoft.Scripting.Hosting.ScriptScope s;
public Form1()
{
InitializeComponent();
py = Python.CreateEngine(); // allow us to run ironpython programs
s = py.CreateScope(); // you need this to get the variables
}
private void doPython()
{
//Step 1:
//Creating a new script runtime
var ironPythonRuntime = Python.CreateRuntime();
//Step 2:
//Load the Iron Python file/script into the memory
//Should be resolve at runtime
dynamic loadIPython = ironPythonRuntime.;
//Step 3:
//Invoke the method and print the result
double n = loadIPython.add(100, 200);
numericUpDown1.Value = (decimal)n;
}
}
}
However, this requires for the file 'first.py' to be wherever the program is once compiled. So if I wanted to share my program I would have to send both the executable and the python files which is very inconvenient. One way I thought to resolve this is by adding the 'first.py' file to the resources and running from there... but I don't know how to do this or even if it is possible.
Naturally the above code will not work for this as .UseFile method takes string arguments not byte[]. Does anyone know how I may progress?
Lets start with the simplest thing that could possibly work, you've got some code that looks a little like the following:
// ...
py = Python.CreateEngine(); // allow us to run ironpython programs
s = py.CreateScope(); // you need this to get the variables
var ironPythonRuntime = Python.CreateRuntime();
var x = py.CreateScriptSourceFromFile("SomeCode.py");
x.Execute(s);
var myFoo = s.GetVariable("myFoo");
var n = (double)myFoo.add(100, 200);
// ...
and we'd like to replace the line var x = py.CreateScriptSourceFromFile(... with something else; If we could get the embedded resource as a string, we could use ScriptingEngine.CreateScriptSourceFromString().
Cribbing this fine answer, we can get something that looks a bit like this:
string pySrc;
var resourceName = "ConsoleApplication1.SomeCode.py";
using (var stream = System.Reflection.Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName))
using (var reader = new System.IO.StreamReader(stream))
{
pySrc = reader.ReadToEnd();
}
var x = py.CreateScriptSourceFromString(pySrc);

Spawn child process from node to run python script returns 500

I'm trying to spawn a child process to run a python script from Node. I have the following request that comes in:
/webcrawler?source=http://www.pygamers.com&method=BFS&nodeCount=3&depth=0&keyword=game
I have verified that my params are coming in correctly. Here is my code set up to handle the request in app.js:
app.get('/webcrawler', function(req, res){
var python = require('child_process').spawn(
'python',
["WebCrawler/Webcrawler.py"
, req.query.source
, req.query.method
, req.query.nodeCount
, req.query.depth
, req.query.keyword]
);
var output = "";
python.stdout.on('data', function(data){ output += data });
python.on('close', function(code){
if (code !== 0) {
return res.send(500, code);
}
return res.send(200, output);
});
});
I am calling my Python script, Webcrawler.py which is in the WebCrawler directory. The WebCrawler directory is in the same directory as app.js.
However, this request is giving me a 500, and I haven't been able to figure out why. It seems like I must be generating the child process incorrectly. I used this answer as a model for doing so.
It needs to be an absolute path, like /home/username/Webcrawler/webcrawler.py
Sounds like a path problem.
Also checkout python-shell package. Makes your life so much easier.
you can check this package on npm- native-python
it provides a very simple and powerful way to run python functions from node
might solve your problem.
import { runFunction } from '#guydev/native-python'
const example = async () => {
const input = [1,[1,2,3],{'foo':'bar'}]
const { error, data } = await runFunction('/path/to/file.py','hello_world', '/path/to/python', input)
// error will be null if no error occured.
if (error) {
console.log('Error: ', error)
}
else {
console.log('Success: ', data)
// prints data or null if function has no return value
}
}
python module
# module: file.py
def hello_world(a,b,c):
print( type(a), a)
# <class 'int'>, 1
print(type(b),b)
# <class 'list'>, [1,2,3]
print(type(c),c)
# <class 'dict'>, {'foo':'bar'}

How to execute Python code generated by Blockly right in the browser?

I was following the example Blockly Code Generators and was able to generate Python codes. But when I run the Python code, I get an error. It seems the error is 'eval(code)' below, what should I do if I want to execute the Python code right inside the browser? Thanks for any help!
Blockly.JavaScript.addReservedWords('code');
var code = Blockly.JavaScript.workspaceToCode(workspace);
try {
eval(code);
} catch (e) {
alert(e);
}
here is the snapshot Unfortunately i dont have enough points to post the image here
Can you try this with a simple code , like - print('Hello World!')
According to the image , the issue could be with indentation , and indentation is very important in python, othewise it can cause syntax errors .
You should have also changed the code to -
Blockly.Python.addReservedWords('code');
var code = Blockly.JavaScript.workspaceToCode(workspace);
try {
eval(code);
} catch (e) {
alert(e);
}
Try to eval with a Python interp written is JS, like http://brython.info/.
as you using eval function of javascript you are actually saying to print the page as print() means to print the page in javascript.
The solution to this is there in the Blockly itself as to rn the code they call this function.
function() {
Blockly.JavaScript.INFINITE_LOOP_TRAP = 'checkTimeout();\n';
var timeouts = 0;
var checkTimeout = function() {
if (timeouts++ > 1000000) {
throw MSG['timeout'];
}
};
var code = Blockly.JavaScript.workspaceToCode(Code.workspace);
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
try {
eval(code);
} catch (e) {
alert(MSG['badCode'].replace('%1', e));
}
The above code is from code.js in demos/code/code.js line 553.

How to scrape location objects?

I have a list of URL's and would like to scrape the location objects for each of their webpages. The data I am referring to is produced by typing "window.location" into your browser's console. For example, performing this action on www.github.com with Chrome would give you the something like following output:
Location {assign: function, replace: function, reload: function, ancestorOrigins: DOMStringList, origin: "https://github.com"…}
When expanded, you can see more information:
Location {
ancestorOrigins: DOMStringList
assign: function () { [native code] }
hash: ""
host: "github.com"
hostname: "github.com"
href: "https://github.com/"
origin: "https://github.com"
pathname: "/"
port: ""
protocol: "https:"
reload: function () { [native code] }
replace: function () { [native code] }
search: ""
toString: function toString() { [native code] }
valueOf: function valueOf() { [native code] }
__proto__: Location
}
I have used Python and the Mechanize library to scrape in the past, but have never desired this functionality until now and am not sure how to proceed. Any suggestions would be welcomed.
As far as I understand, you want to perform a JavaScript call on desired web page. My suggestion would be to use some headless browsers. I did similar things with Framework called PyQt4. You can also use other headless web browsers like PhantomJS. Or you may also be interesting with tool called Selenium.

Categories

Resources