2401_87602309 2024-12-23 12:09 采纳率: 55.6%
浏览 53
已结题

python接收HTML的get数据

单片机ESP32充当服务器,手机通过WiFi连接服务器,在手机上输入内容,需要在后台ESP32端打印出来,目前ESP32可以收到数据,但是但打印不出来。

python代码如下:

#导入Pin模块
import _thread
import sys
import machine
import onewire
from machine import Pin
import time
import network
import socket


#定义LED控制对象
led1=Pin(33,Pin.OUT,Pin.PULL_DOWN)#wifi链接


#连接的WIFI账号和密码
ssid = "309"
password = "1234567890"

#WIFI连接
def wifi_connect():
    wlan=network.WLAN(network.STA_IF)  #STA模式
    wlan.active(True)  #激活
    
    if not wlan.isconnected():
        print("conneting to network...")
        wlan.connect(ssid,password)  #输入 WIFI 账号密码
        
        while not wlan.isconnected():
            led1.value(1)
            time.sleep_ms(300)
            led1.value(0)
            time.sleep_ms(300)
        led1.value(0)
        return False
    else:
        led1.value(0)
        print("network information:", wlan.ifconfig())
        return True
    
    


#网页数据
def web_page():

    html = """<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>交互页面</title>
</head>

<body>  
  
<h2>提交你的信息</h2>  
<form name="form1" method="Get" action="">
  <label for="textfield"></label>
  
 <table width="381" border="0">
  <tr>
    <td width="93">姓名</td>
    <td width="272"><input type="text" name="name" id="name"></td>
  </tr>
  <tr>
    <td>性别</td>
    <td><label for="textfield2"></label>
      <input type="text" name="name1" id="name1"> </td>
  </tr>
  <tr>
    <td colspan="2"><input type="submit" name="button" id="button" value="提交"></td>
   </tr>
</table>
</form>
</body>  
</html>"""
    return html



#程序入口
if __name__=="__main__":
    
    if wifi_connect():
        #SOCK_STREAM表示的是TCP协议,SOCK_DGRAM表示的是UDP协议
        my_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #创建socket连接
        # 将socket对象绑定ip地址和端口号
        my_socket.bind(('', 80))
        # 相当于电话的开机 括号里的参数表示可以同时接收5个请求
        my_socket.listen(5)
        
        while True:

            # 进入监听状态,等待别人链接过来,有两个返回值,
            #一个是对方的socket对象,一个是对方的ip以及端口
            client, addr = my_socket.accept()
            print('Got a connection from %s' % str(addr))
            # recv表示接收,括号里是最大接收字节
            request = client.recv(1024)
        
            request = str(request)
            print (request)
         
            response = web_page()
            client.send('HTTP/1.1 200 OK\n')
            client.send('Content-Type: text/html\n')
            client.send('Connection: close\n\n')
            client.sendall(response)
            client.close()
  • 写回答

31条回答 默认 最新

  • 问答-莫得感情 2024-12-23 12:13
    关注

    ️题主您好️,目前由我为您解答👇🏼
    🧡参考谷歌智能助手,由吾为汝整理提供🧡

    你的问题在于没有从接收到的 HTTP 请求中解析 GET 参数。目前的代码只是打印了整个原始请求,并没有提取 namename1 的值。

    以下是修改后的代码,能够正确解析并打印 GET 参数:

    # ... (之前的导入和 WiFi 连接代码)
    
    def web_page():
        # ... (之前的 web_page 函数)
    
    def parse_get_params(request):
        """解析 GET 请求参数"""
        params = {}
        try:
            start_index = request.find("GET /?") + 6  # GET 请求参数的起始位置
            end_index = request.find(" HTTP/1.1")
            query_string = request[start_index:end_index]
            pairs = query_string.split("&")
            for pair in pairs:
                key_value = pair.split("=")
                if len(key_value) == 2:
                    key = key_value[0]
                    value = key_value[1].replace("+", " ") # 处理空格,将 '+' 替换成空格
                    params[key] = value
        except:
            pass # 处理解析错误,例如没有找到 GET 参数
        return params
    
    
    # 程序入口
    if __name__ == "__main__":
        if wifi_connect():
            # ... (之前的 socket 设置代码)
    
            while True:
                client, addr = my_socket.accept()
                print('Got a connection from %s' % str(addr))
                request = client.recv(1024)
                request = str(request)
    
                print("Raw Request:", request) # 打印原始请求
    
                params = parse_get_params(request)
                print("Parsed GET parameters:", params) # 打印解析后的参数
    
                if "name" in params:
                    print("Name:", params["name"])
                if "name1" in params:
                    print("Name1:", params["name1"])
    
    
                response = web_page()
                client.send('HTTP/1.1 200 OK\n')
                client.send('Content-Type: text/html\n')
                client.send('Connection: close\n\n')
                client.sendall(response)
                client.close()
    

    主要改动:

    1. 添加了 parse_get_params 函数: 这个函数负责从 HTTP 请求字符串中提取 GET 参数。它查找 GET /? HTTP/1.1 之间的字符串,然后将其解析成字典。 重要: 添加了对空格的处理,将 + 替换成空格。URL编码中空格会被编码成 +

    2. 调用 parse_get_params 函数: 在接收到请求后,调用该函数解析参数,并将结果存储在 params 字典中。

    3. 打印解析后的参数和各个值: 打印 params 字典以及 namename1 的值。

    使用方法:

    1. 将代码上传到 ESP32。
    2. 在手机浏览器中输入 ESP32 的 IP 地址。
    3. 填写表单并提交。
    4. 在 ESP32 的串口监视器中,你应该能看到类似以下的输出:
    Raw Request: b'GET /?name=Test+Name&name1=Male HTTP/1.1\r\nHost: 192.168.4.1\r\nConnection: keep-alive\r\n...'
    Parsed GET parameters: {'name': 'Test Name', 'name1': 'Male'}
    Name: Test Name
    Name1: Male
    

    这个改进的代码能够正确解析 GET 请求参数,并打印出你想要的信息。记住,处理用户输入时要注意安全性和潜在的错误,例如参数缺失或格式错误。 为了更健壮的解决方案,可以考虑使用 MicroPython 的 urequestsuasyncio 库来简化网络编程,并使用更完善的 HTTP 解析方法。

    希望这个解决方案对你有帮助!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(30条)

报告相同问题?

问题事件

  • 系统已结题 1月3日
  • 已采纳回答 12月26日
  • 赞助了问题酬金15元 12月23日
  • 创建了问题 12月23日