【问题标题】:Python respond to HTTP RequestPython 响应 HTTP 请求
【发布时间】:2013-10-17 18:57:48
【问题描述】:

我正在尝试做一些我认为非常简单的事情,但是由于我对 Python 还很陌生,所以我无法找到如何去做。调用 URL 时,我需要在 Python 脚本中执行一个函数。

例如,我会在浏览器中访问以下 URL(192.168.0.10 是我正在运行脚本的计算机的 IP,8080 是选择的端口)。

http://192.168.0.10:8080/captureImage

当访问此 URL 时,我想在我的 Python 脚本中执行一个操作,在这种情况下执行我创建的一个函数。

我知道这可能相当简单,但我无法弄清楚如何做到这一点。我将不胜感激!

【问题讨论】:

  • 首先,您需要一个 Web 服务器。您是否已经在该计算机上安装并运行了 Web 服务器?
  • 如果您使用 Windows,此链接可能有效*.com/questions/3179657/python-webbrowser-question
  • 我想你误解了我的意思。我希望 Python 脚本充当某种 Web 服务器,但我不需要提供任何文件。当客户端访问服务器上的 URL 时,我需要能够执行一个函数。

标签: python httprequest


【解决方案1】:

这在python中确实很简单:

import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler

def some_function():
    print "some_function got called"

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/captureImage':
            # Insert your code here
            some_function()

        self.send_response(200)

httpd = SocketServer.TCPServer(("", 8080), MyHandler)
httpd.serve_forever()

根据您想从哪里开始,您可能需要查看 BaseHttpServer 的文档,或者查看功能更全的 Web 框架,例如 Django。

【讨论】:

  • 这正是我想要的,谢谢!但是,我遇到了另一个问题。当我使用您的代码启动脚本时,Web 服务器会停止执行脚本的其余部分。这是一个问题,因为我需要在调用 URL 时从我的脚本中执行一个函数。我将如何解决这个问题?
  • @Lazze - 我更新了示例以包含函数调用,这有帮助吗?澄清一下,您是否希望网络服务器只处理一个请求然后关闭?或者是 httpd.serve_forever() 行之后的代码永远不会运行的问题? (在这种情况下,您可以将 httd.server_forever() 行向下移动到脚本的末尾)
  • 有些代码在serve_forever() 之后永远不会运行。当我回到家时,我会尝试将它移动到我的脚本底部,会报告回来。感谢您迄今为止的帮助!
  • @Lazze 请记住,python 脚本从上到下逐行执行。由于 serve_forever 进入了一个循环,你必须在某个时候打破它(你可以调用 self.shutdown() 来停止服务器)。如果你想调用一个函数,就像我对“some_function”所做的那样,确保函数定义在调用它的代码之前。如果您希望我查看您的代码,请随时使用您的代码更新帖子或创建一个新问题。
  • 如果我的代码中有另一个永远不会结束的循环怎么办?那么将 server_forever() 放在我的代码底部仍然有效吗?
【解决方案2】:

实现您所需的一种可靠方法是使用 Python Web 框架 Flask (http://flask.pocoo.org/)。有一些 Youtube 视频很好地解释了 Flask 基础知识 (https://www.youtube.com/watch?v=ZVGwqnjOKjk)。

这是我的运动检测器的一个例子,当我的猫在门口等着时,它会发短信给我。触发此代码所需要做的就是在地址(在我的情况下)http://192.168.1.112:5000/cat_detected 处的 HTTP 请求@

   from flask import Flask
   import smtplib
   import time


   def email(from_address, to_address, email_subject, email_message):
       server = smtplib.SMTP('smtp.gmail.com:587')
       server.ehlo()
       server.starttls()
       server.login(username, password)
       # For character type new-lines, change the header to read: "Content-Type: text/plain". Use the double \r\n.
       # For HTML style tags for your new-lines, change the header to read:  "Content-Type: text/html".  Use line-breaks <br>.
       headers = "\r\n".join(["from: " + from_address, "subject: " + email_subject,
                       "to: " + to_address,
                       "mime-version: 1.0",
                       "content-type: text/plain"])
       message = headers + '\r\n' + email_message
       server.sendmail(from_address, to_address, message)
       server.quit()
       return time.strftime('%Y-%m-%d, %H:%M:%S')


   app = Flask(__name__)


   @app.route('/cat_detected', methods=['GET'])
   def cat_detected():
       fromaddr = 'CAT ALERT'
       admin_addrs_list = [['YourPhoneNumber@tmomail.net', 'Mark']]  # Use your carrier's format for sending text messages via email.
       for y in admin_addrs_list:
           email(fromaddr, y[0], 'CAT ALERT', 'Carbon life-form standing by the door.')
       print('Email on its way!', time.strftime('%Y-%m-%d, %H:%M:%S'))
       return 'Email Sent!'

   if __name__ == '__main__':
       username = 'yourGmailUserName@gmail.com'
       password = 'yourGmailPassword'
       app.run(host='0.0.0.0', threaded=True)

【讨论】: