[英]How to extract data from incoming HTTP POST using python
I have a Ubuntu LAMP webserver and data is being sent to the webserver continuously through HTTP POST method.我有一个 Ubuntu LAMP 网络服务器,数据通过 HTTP POST 方法不断发送到网络服务器。 I need to extract the data from HTTP POST and insert them in a Database.
我需要从 HTTP POST 中提取数据并将它们插入到数据库中。 I don't know how to do that.
我不知道该怎么做。 There is a lot of example available on how to handle outgoing HTTP POST request but the incoming HTTP POST request.
有很多关于如何处理传出的 HTTP POST 请求但传入的 HTTP POST 请求的示例。 I want to write a python3 script which will extract the data from incoming HTTP POST request and save them as varible which I will use to insert the data into the database and also return a response to the client.Can anybody help me in this regard?
我想编写一个 python3 脚本,它将从传入的 HTTP POST 请求中提取数据并将它们保存为变量,我将用它来将数据插入数据库并向客户端返回响应。有人可以在这方面帮助我吗?
UPDATE UPDATE
According to the code you posted below, here is a working answer. 根据您在下面发布的代码,这是一个有效的答案。
#!/usr/bin/python3
import socketserver
from http.server import BaseHTTPRequestHandler
import time
import threading
def do_something(site_id, first, last, pass1):
print(site_id)
print(first)
print(last)
print(pass1)
#just to illustrate the point and print the variables
class MyHandler(BaseHTTPRequestHandler):
def do_POST(self): # !important to use 'do_POST' with Capital POST
global site_id, first, last, pass1 #those are still undefined at the module level ;) remember this for later
if self.path == '/do_something':
request_headers = self.headers
site_id = request_headers["m_site_name"]
first = request_headers["m_first_name"]
last = request_headers["m_last_name"]
pass1 = request_headers["m_device_name"]
do_something(site_id, first, last, pass1)
self.send_response(200)
self.end_headers() #as of P3.3 this is required
try:
httpd = socketserver.TCPServer(("localhost", 9001), MyHandler)
httpd.serve_forever()
finally:
httpd = socketserver.TCPServer(("localhost", 9001), MyHandler)
httpd.server_close()
Calling it with Postman 用邮递员打电话
and the command line output is 命令行输出是
C:\\Development\\Python\\test\\venv\\Scripts\\python.exe C:/Development/Python/test/webserver_old.py 1001 jyoti0 127.0.0.1 - - [19/Nov/2018 21:53:45] "POST /do_something HTTP/1.1" 200 - jyoti1 101
I combined answers from these here: Reference one , two and third And this is also very important to read: https://docs.python.org/3/library/http.server.html 我在这里结合从这些问题的答案:参考一个 , 2和第三 ,这也是非常重要的阅读: https://docs.python.org/3/library/http.server.html
http.server is not recommended for production.
不建议将http.server用于生产。 It only implements basic security checks.
它仅实现基本的安全检查。
I believe is ok for a small implementation and some testing around or proof of concept but eventually you'll need to manage this better, maybe I can suggest you to spend some time and use Flask , is actually an excellent & very light framework for Python API building and prototyping. 我相信可以进行一个较小的实现,并进行一些测试或概念验证,但最终您需要更好地进行管理,也许我可以建议您花一些时间并使用Flask ,这实际上是Python的出色且非常轻便的框架API构建和原型制作。
- -
As per a very light and simple reference to this one: 根据对此的非常简短的参考:
def do_POST(self):
# Doesn't do anything with posted data
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length) # <--- Gets the data itself
self._set_headers()
self.wfile.write("<html><body><h1>POST!</h1></body></html>")
Update (without and API): 更新(不包含API):
Assuming you are running on or machine at a custom port with a custom trailing part at the URL, then "pure" python would look like this: 假设您在URL上带有自定义尾部的自定义端口上运行或运行在计算机上,则“ pure” python如下所示:
import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler
def doSomething():
print "i did"
class MyHandler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path == '/doSomething':
mail = self.request.POST.get('email')
something = self.request.POST.get('something')
doSomething()
self.send_response(200)
httpd = SocketServer.TCPServer(("", 8080), MyHandler)
httpd.serve_forever()
I assume this way you can reuse the variables freely. 我假设您可以自由地重用变量。 Check also this reference here , Brenda's answer.
也可以在这里查看此参考资料, 这是布伦达的答案。
@oetoni, I am getting time out error while using: @oetoni,使用时出现超时错误:
#!/usr/bin/python3
import socketserver
from http.server import BaseHTTPRequestHandler
import time
import threading
def do_something(site_id, first, last, pass1):
print(site_id)
print(first)
print(last)
print(pass1)
#just to illustrate the point and print the variables
class MyHandler(BaseHTTPRequestHandler):
def do_POST(self): # !important to use 'do_POST' with Capital POST
global site_id, first, last, pass1 #those are still undefined at the module level ;) remember this for later
if self.path == '/do_something':
request_headers = self.headers
site_id = request_headers["m_site_name"]
first = request_headers["m_first_name"]
last = request_headers["m_last_name"]
pass1 = request_headers["m_device_name"]
do_something(site_id, first, last, pass1)
self.send_response(200)
self.end_headers() #as of P3.3 this is required
try:
httpd = socketserver.TCPServer(("localhost", 9001), MyHandler)
httpd.serve_forever()
finally:
httpd = socketserver.TCPServer(("localhost", 9001), MyHandler)
httpd.server_close()
But I am getting the correct response while using this code: 但是在使用此代码时,我得到了正确的响应:
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import cgi
import cgitb
cgitb.enable()
print('Content-Type: text/html')
print('')
arguments = cgi.FieldStorage()
for i in arguments.keys():
print(arguments[i].value)
and it prints the received data on the web browser. 并在网络浏览器上打印接收到的数据。 I am using this script as a cgi script on the apache web server which can be accessed through a web browser.
我将此脚本用作可通过Web浏览器访问的apache Web服务器上的cgi脚本。 I am not running this script as a service or application.
我没有将此脚本作为服务或应用程序运行。
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import cgi
import cgitb
cgitb.enable()
print('Content-Type: text/html\n')
arguments = cgi.FieldStorage()
print(arguments["m_site_name"].value)
print("<br />\n")
print(arguments["m_first_name"].value)
print("<br />\n")
print(arguments["m_last_name"].value)
print("<br />\n")
print(arguments["m_device_name"].value)
print("<br />\n")
site = arguments["m_site_name"].value
first = arguments["m_first_name"].value
last = arguments["m_last_name"].value
device = arguments["m_device_name"].value
-----do_other_things_with_the_variables(site,first,last,device)-----
This code solved my problem. 这段代码解决了我的问题。 Now I can store HTTP POST data into variables with this python cgi script.
现在,我可以使用此python cgi脚本将HTTP POST数据存储到变量中。
my HTTP POST Request: http://your_server_url_or_IP/cgi-bin/python_script.py?m_site_name=MySite&m_first_name=anyname&m_last_name=anylastanme&m_device_name=anydeviceidorname 我的HTTP POST请求: http://your_server_url_or_IP/cgi-bin/python_script.py?m_site_name = MySite&m_first_name = anyname&m_last_name = anylastanme&m_device_name = anydeviceidorname
With python3, inside do_POST()
of your handler class based on http.server.*Handler
:使用 python3,在基于
http.server.*Handler
程序类的do_POST()
中:
import cgi
enctype, attrs = cgi.parse_header(self.headers['Content-Type'])
if enctype == 'multipart/form-data':
boundary = {'boundary': attrs['boundary'].encode() }
form_data = cgi.parse_multipart(self.rfile, boundary)
file_content = form_data.get('myfile')
fname = 'data/uploads/' + str(time.time()) + '.json'
with open(fname, 'wb') as fp:
for part in file_content:
fp.write(part)
Don't forget to insert Content-Length check to limit the max file size.不要忘记插入 Content-Length 检查以限制最大文件大小。 Presumably cgi.FieldStorage stops reading when
limit
bytes reached (if specified) and also deals better with large files in general.大概cgi.FieldStorage 在达到
limit
字节(如果指定)时停止读取,并且通常也能更好地处理大文件。 This is not part of official doc .这不是官方文档的一部分。 I read it in the source file
cgi.py
.我在源文件
cgi.py
阅读了它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.