【问题标题】:running client-side python script at a click of a button (on a webpage)单击按钮(在网页上)运行客户端 python 脚本
【发布时间】:2012-06-29 08:02:57
【问题描述】:

所以我正在尝试修改一些 HTML 以具有一个按钮,该按钮启动一个 python 脚本,该脚本作用于自己系统中的一些文件。

更具体地说,我有一个 python 脚本,它可以读取 snort 日志并生成一个指向新网站的链接(实际上,一个 IP 地址,它采用数据包捕获流搜索的参数) 我正在尝试将此脚本实现为网站上的按钮。 -注意:如果点击按钮的人需要在他们自己的机器上拥有 script.py 也没关系

尝试在这个主题上做我的功课,但似乎有无限的选择 - 其中大部分都没有得到任何 2 方的同意。 我需要一个框架吗?我不能只使用我的 HTML 代码中的一些 或其他内容从其目录中调用我的 python 脚本吗?

【问题讨论】:

    标签: python html frameworks


    【解决方案1】:

    简短的回答:你不能。

    您无法从浏览器访问用户机器上的文件,更不用说执行它们。想象一下这会有多大的安全漏洞。

    但是,您可以在许多 GUI 工具包(Qt 或 wx 具有 Web 视图或类似工具)中实现自己的简单 Web 浏览器(例如,显示单个页面)。或者,您需要为您正在使用的浏览器开发(或查找)一个插件/插件,并与之通信。这将取决于每个浏览器等。我不知道这是否可行。或者,用户将下载一个他将选择运行而不是保存的文件,该文件将执行您的脚本。

    实际上,我刚刚看到thisthis 基本上是您安装的插件(基于IronPython 和Silverlight),但我不确定您是否可以执行用户系统上的脚本。它可以执行嵌入在页面中的代码。

    【讨论】:

    • 所以,假设我将我的 python 和 snort 日志文件发送给自己(在另一台机器上)。我无法创建一个按钮,当我从另一台机器访问网页并单击时,会触发该 python 代码的运行(在同一台机器上)给定相同的名称、位置等?跨度>
    • 不,也许这可以通过我提到的最后一个选项来实现,尽管我从未尝试过。您可以将该文件嵌入 HTML 中,如果可能的话,可能会将这些文件放在服务器上以便于访问...
    • 顺便说一句 - 只是从您发布的链接中轻松浏览,我想我已经对我在做什么有了更好的处理。非常感谢这些
    • 好吧,目前我只是在整理一份可能的清单(直到明天早上我才能真正深入了解)。不过,到目前为止,我认为我的首选选项如下:使用 py2exe 创建可执行文件(通过您对可下载文件的建议提醒我这一点);以某种方式使网页可以访问 snort 文件,并嵌入代码(ironPython 风格);只是让用户下载我的 friggin 代码并在他自己的 python shell 上运行它!
    • 也在考虑使用 python-to-java 编译器。没有嵌入 javascripts 的经验,但从我迄今为止发现的情况来看,它似乎更兼容 HTML。然而,这并没有解决 snort 警报文件的可访问性
    【解决方案2】:

    OP 问题的替代解决方案:

    解决方案概要:

    1. 使用“GET”通过 HTML 表单发送用户输入
    2. 处理来自发送到 shell 脚本的 url 编码值“GET”中的值
    3. Shell 脚本解析值并保存它们,并将参数传递给 Python 脚本,同时调用它运行。

    Javascript 和 php 可以很好地与此设置配合使用,并允许从那里使用 mysql 等。

    使用“GET”,我们使用 shell 脚本将用户的输入从客户端发送到服务器端以处理我们的数据。

    示例索引.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>
    

    调用 Python 脚本的示例 shell 脚本,该脚本将位于您的 cgi-bin 或其他指定的“可执行”允许目录中。

    #!/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>'
    

    Python 脚本示例。

    从 shell 脚本调用:

    #!/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)
    

    完整的工作示例位于此处: https://github.com/mhenes/Google-EmailScraper

    免责声明这是我的 git- 使用分叉项目来展示此功能。

    【讨论】:

      【解决方案3】:

      IronPython 可能是您正在寻找的解决方案: http://ironpython.net/

      通过以下链接中提供的教程和代码,您应该能够创建响应事件的 html 元素,例如您提到的 html“按钮”。

      我一直在使用 IronPython,并且在对脚本的内部和外部调用方面取得了成功。下面的教程很可能包含您可能遇到的任何其他问题。

      helloworld.html -

      IronPython 警报示例,文档中的内部 python 脚本。

      要在浏览器中开发 Python 应用程序,您只需要您喜欢的文本编辑器即可;所以打开它,创建一个 HTML 文件,引用 dlr.js,然后你就可以使用 script-tags 来运行 Python 代码了:

      <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

      要在 REPL 窗口中执行此操作,所以让我们在浏览器中打开一个;只需在页面中放置以下脚本标签:

      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 示例:用于添加 DOM 元素并将其 HTML 内容更改为“哎哟!”点击时:

      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
      

      注意事项:IronPython 需要 SilverLight,因此它只适用于 FireFox 或 Safari。

      与您的问题相关的优秀教程: http://jimmy.schementi.com/2010/03/pycon-2010-python-in-browser.html

      【讨论】:

      • 是的,从一开始就有一个很好的、写得好的、格式化的帖子。
      • @mhenes 请在回答前阅读this
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 2014-10-01
      相关资源
      最近更新 更多