简体   繁体   中英

running client-side python script at a click of a button (on a webpage)

So I'm trying to modify some HTML to have a button that initiates a python script that acts on a few files in ones own system.

more specifically, i have a python script that reads through snort logs and produces a link to a new website (really, an IP address that takes parameters for a packet-capture stream search) I'm trying to implement this script as a button on a website. -note: it's ok if whoever is clicking on the button(s) needs to have the script.py on their own machine

I've tried to do my homework on the subject, but there seem to be infinite options - most of which aren't agreed upon by any 2 parties. Do i NEED a framework? can i not just call my python script from its directory using some < script / >'s or something in my HTML code?

Short answer: you can't.

You can't access files on the user's machine, and even less execute them, from the browser. Imagine how much of a security hole that would be.

However, you could implement your own simple web browser (that displays a single page for example) in many GUI toolkits (Qt or wx have web views or similar). Or, you would need to develop (or find) a plugin/addon to the browser you are using, and communicate with that. It will depend on each browser, etc. I have no idea if this is feasible. Or, the user will download a file which he will choose to run instead of save, that will execute your script.

Actually, I just saw this and this which is basically a plugin that you install (based on IronPython and Silverlight), I'm not sure you can execute scripts that are on the user's system though. It can execute code embedded in the page.

Alternative Solution to the OPs question:

Synopsis of solution:

  1. Send user input via HTML Form with 'GET'
  2. Process values from the url encoded values 'GET' sent to the shell script
  3. Shell script parses values and saves them passing the arguments to the Python script while calling it to run.

Javascript and php work nicely with this setup and allows for mysql, etc. from there.

Using 'GET' we send the user's input from client side to server side using a shell script to process our data.

Example Index.php

<!DOCTYPE html>
<html>
    <head>
    <title>Google Email Search</title>  
    </head>
<body>
    <h1>Script Options</h1>
<form action="/cgi-bin/call.sh" method="get">       
    <TABLE BORDER="1">
        <TR>
            <TD>Keyword:</TD>
            <TD><input type="text" name="query" value="Query"></TD>
        </TR>
        <TR>
            <TD># of Pages:</TD>
            <TD><input type="text" name="pages" value="1"></TD>
        </TR>
        <TR>
            <TD>Output File Name:</TD>
            <TD><input type="text" name="output_name" value="results"></TD>
        </TR>
        <TR>
            <TD>E-mail Address:</TD>
            <TD><input type="text" name="email_address" value="example@gmail.com">         
            </TD>
        </TR>
        <TR>
            <TD><input type="submit" value="Submit"></TD>
        </TR>
    </TABLE>
</form>
</body>
</html>

Example shell script to call the python script which would be located in your cgi-bin or other designated 'executable' allowed directory.

#!/bin/bash
# Runs the cgi-script, using the shell, using 'get' results from the index html form we parse it to the options in the python script.

echo "Content-type: text/html"
echo ""

echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'

echo '<title></title>'
echo '</head>'
echo '<body>'
query=`echo "$QUERY_STRING" | sed -n 's/^.*query=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
pages=`echo "$QUERY_STRING" | sed -n 's/^.*pages=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
output_name=`echo "$QUERY_STRING" | sed -n 's/^.*output_name=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
email_address=`echo "$QUERY_STRING" | sed -n 's/^.*email_address=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"`
echo '<h1>'
echo 'Running...'
echo '</h1>'
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "$DIR"
python main.py -query $query -pages $pages -o $output_name
echo ''

echo '</body>'
echo '</html>'

Example Python script.

called from the shell script:

#!/usr/bin/env python
from xgoogle.search import GoogleSearch
import urllib2, re, csv, os
import argparse

class ScrapeProcess(object):
emails = []  # for duplication prevention

def __init__(self, filename):
    self.filename  = filename
    self.csvfile   = open(filename, 'wb+')
    self.csvwriter = csv.writer(self.csvfile)

def go(self, query, pages):
    search = GoogleSearch(query)
    search.results_per_page = 10

    for i in range(pages):
        search.page = i
        results = search.get_results()
        for page in results:
            self.scrape(page)

def scrape(self, page):
    try:
        request = urllib2.Request(page.url.encode("utf8"))
        html    = urllib2.urlopen(request).read()
    except Exception, e:
        return

    emails = re.findall(r'([A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*)', html)

    for email in emails:
        if email not in self.emails:  # if not a duplicate
            self.csvwriter.writerow([page.title.encode('utf8'), page.url.encode("utf8"), email])
            self.emails.append(email)

parser = argparse.ArgumentParser(description='Scrape Google results for emails')
parser.add_argument('-query', type=str, default='test', help='a query to use for the Google search')
parser.add_argument('-pages', type=int, default=10, help='number of Google results pages to scrape')
parser.add_argument('-o', type=str, default='emails.csv', help='output filename')    

args   = parser.parse_args()
args.o = args.o+'.csv' if '.csv' not in args.o else args.o  # make sure filename has .csv extension

s = ScrapeProcess(args.o)
s.go(args.query, args.pages)

Full working example located here: https://github.com/mhenes/Google-EmailScraper

Disclaimer this is my git- using a forked project to show this functionality.

IronPython may have been the solution you were looking for: http://ironpython.net/

With the tutorials and code provided in the below link, you should be able to create html elements that react to events such as an html "button" like you mentioned.

I've been playing with IronPython and have had success with internal and external calls to scripts. The tutorial below most likely contains any other questions you may have.

helloworld.html -

IronPython alert example, internal python scripting in document.

To develop a Python application in the browser, you just need your favorite text editor; so open it up, create a HTML file, reference dlr.js, and then you can use script-tags for running Python code:

<html>
<head>
<script src="http://gestalt.ironpython.net/dlr-latest.js"
        type="text/javascript"></script>
</head>
<body>
<script type="text/python">
  window.Alert("Hello from Python")
</script>
</body>
</html>

repl.py

to do this in a REPL window, so let's turn one on in the browser; just place the following script-tag in the page:

from Microsoft.Scripting.Silverlight import Repl

if 'document' not in globals():
  import System
  document = System.Windows.Browser.HtmlPage.Document
if 'window' not in globals():
  import System
  window = System.Windows.Browser.HtmlPage.Window

class PythonRepl(object):
  __ironpython__ = 'silverlightDlrRepl1'
  __minimize__ = 'silverlightDlrWindowLink'
  __container__ = 'silverlightDlrWindowContainer'

  def __init__(self):
    self.repl = Repl.Show('python')

  def hide_all_panels(self):
    window.Eval("sdlrw.hideAllPanels(document.getElementById(\"%s\"))" % self.__minimize__)

  def show_panel(self, id):
    window.Eval("sdlrw.showPanel(\"%s\")" % id)

  def show_ironpython(self):
    self.show_panel(self.__ironpython__)

  def remove(self):
    document.Body.RemoveChild(document.silverlightDlrWindowContainer)

def show():
  prepl = PythonRepl()
  repl = prepl.repl
  import sys
  sys.stdout = repl.OutputBuffer
  sys.stderr = repl.OutputBuffer
  return prepl

if document.QueryString.ContainsKey('console'): 
  prepl = show()
  if document.QueryString['console'] == 'hide':
    prepl.hide_all_panels()
  else:
    prepl.show_ironpython()

dom.py

IronPython example: for adding a DOM element and changing it's HTML content to "Ouch!" when clicked:

dir(document) 
div = document.CreateElement("div")
div.innerHTML = "Hello from Python!"
document.Body.AppendChild(div)
div.id = "message"
div.SetStyleAttribute("font-size", "24px")
def say_ouch(o, e):
    o.innerHTML = "Ouch!"

document.message.events.onclick += say_ouch

Caveat to note: IronPython requires SilverLight and therefore it will only work with FireFox or Safari.

Excellent tutorial related to your question: http://jimmy.schementi.com/2010/03/pycon-2010-python-in-browser.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM