Heitor Giacomini
Heitor Giacomini

Reputation: 484

How to execute a python script with selenium called by php through apache server?

I want to execute the following script in Python through my site in local apache server:

#!/Python34/python
from selenium import webdriver 
driver=webdriver.Firefox()
driver.get("C:\wamp64\www\desenvol\index.html")
elem1 = driver.find_element_by_link_text("call another page")
elem1.click()

The apache is rightly configured and this is the page that I'm using with the php code:

<!doctype html>
<html>
<head>
<title>Light Controller</title>
</head>


<?php
if (isset($_POST['LightON']))
{
exec('python hello.py');
echo("on");
}
?>

<form method="post">
<button name="LightON">Light ON</button>&nbsp;
</form> 


</html>

Upvotes: 2

Views: 1919

Answers (2)

Heitor Giacomini
Heitor Giacomini

Reputation: 484

I did not solve it in the easy way. So, that is what I do:

  • First I created a database with one table and two columns (id and 'numero')
  • Then I make a loop in python for take the value from 'numero' in a specific id (0) and to compare if this value is changed, if this happens the python will execute the web driver command
  • Finally, I make a php script, inside my html page, to update this value in that specific id(0)

So, that is my code...

The python final code:

#!/Python34/python  
#from __future__ import print_function #NAO NECESSARIO Estava No exemplo do PyMySQL,aparentemente nao necessario
import time #Importa a função do delay
import pymysql #importa biblioteca para conexao com o python
from selenium import webdriver #biblioteca que me permite acessar o navegador 
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='samsung', db='tccdia')#string de conexao com o MySQL
status = 1 #defina essa variavel para funcionar como uma chave que impede a execução do webdriver assim que o script iniciar 
ValorReferencia = 1 #valor para verificar se o valor do DB foi altera
#chave = 0 #NAO NECESSARIO
while 1<2:
    cur = conn.cursor()
    cur.execute("SELECT numero FROM cw_lampada WHERE id = 0")
    result = cur.fetchone()#criei uma variavel para armazenar esse valor porque ele apaga 
    ValorAtual = result
    ValorAtual = ValorAtual[-1] # Tira aspas e virgulas Funcionou mas nao entendi o procedimento
    print ("valor atual: ",ValorAtual," tipo: " ,type(ValorAtual))      
    if status == 1:
        ValorReferencia = ValorAtual
        status = 0
        #chave=1 #NAO NECESSARIO
    print ("valor referencia: ",ValorReferencia," tipo: " ,type(ValorReferencia))       
    #if chave ==1: ##NAO NECESSARIO Maybe this if ins't necessary
    if ValorAtual != ValorReferencia :
        driver=webdriver.Firefox() #Abre o navegador em determinado endereco e abre link
        driver.get("C:\wamp64\www\desenvol\index.html")
        elem1 = driver.find_element_by_link_text("call another page")
        elem1.click()
        driver.close()
        status = 1
        #chave = 0 #NAO NECESSARIO
    cur.close()
    time.sleep(2) #tempo de espera  
#conn.close() #NAO NECESSARIO nao faria sentido ficar abrindo e fechando conexao se o tempo de reconexao eh curto

The MySQL database was something like:

create database tccdia;
use tccdia;
create table cw_lampada(
  id int primary key,
  numero int
);

And the HTML was:

<!doctype html>
<html lang="pt_BR">
<head>
    <meta charset="utf-8">
    <title>lampada</title>
</head>
<body>
    <?php
        require 'config.php';
        require 'connection.php'; #connection deve ser chamado anetes do database
        require 'database.php'; 
    ?>
<form action="" method="post">
         <input type="submit" value="Clicar" name="botao" style="width: 900px; height: 200px;">
    </form>

    <?php
    if(isset($_POST["botao"])){
         echo "botão foi clicado";
         $numero = $numero+1;
             
         $atualizar = array(
                'numero' => $numero
            );                                                                      
        DBUpdate('lampada', $atualizar, 'id=0'); 
    ?>   
</body>
</html>

Of course, there is a more easy and direct way to resolve this, but it is what I did. I hope I have been useful for other with the same problem.

Upvotes: 0

Pedro Lobito
Pedro Lobito

Reputation: 98921

Provide the full path to the python script, i.e.:

shell_exec('python /full/path/to/hello.py');

If you want to play safe, also provide the full path to the python binary.

shell_exec('/usr/local/bin/python /full/path/to/hello.py');

To find the full path to the python binary open the shell and type:

which python

  1. Make sure the apache user has execute permissions on hello.py.
  2. I don't see any element with text "call another page" on your html.

Update:

You can also use python's SimpleHTTPServer, something like:

from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse
class GetHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        parsed_path = urlparse.urlparse(self.path)
        self.send_response(200)
        self.end_headers()
        #self.wfile.write(message)
        if (parsed_path.query == "LightON"):
            from selenium import webdriver 
            driver=webdriver.Firefox()
            driver.get("http://stackoverflow.com")
            elem1 = driver.find_element_by_link_text("Questions")
            elem1.click()
            self.wfile.write("Command Executed")
        return

if __name__ == '__main__':
    from BaseHTTPServer import HTTPServer
    server = HTTPServer(('localhost', 8080), GetHandler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

The above code will open a webserver on port 8080, and wait for a LightON request, after receiving it, executes the selenium code.

to activate it just create a link to it, something like

<a href="http://localhost:8080/LightON"> LightON </a>

PS: I've tested the code and it works as expected.

Upvotes: 2

Related Questions