python --http请求模拟器(tk)

import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import requests
from requests.exceptions import RequestException
import json
from datetime import datetime
import re


class RequestSimulator(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("HTTP请求模拟器")
        self.geometry("800x650")

        self.method_var = tk.StringVar(value="GET")  # 方法选择

        self.json_tags = {
            "key": "#0066cc",  # 键名:蓝色
            "string": "#009933",  # 字符串:绿色
            "number": "#ff6600",  # 数字:橙色
            "boolean": "#cc00cc",  # 布尔值:紫色
            "null": "#888888",  # null:灰色
            "brace": "#333333",  # 大括号/中括号:深灰色
            "colon": "#333333",  # 冒号:深灰色
            "comma": "#333333"  # 逗号:深灰色
        }

        self.create_widgets()
        self.init_json_highlight_tags()  # 初始化高亮标签


    def create_widgets(self):
        # 顶部控制区域
        top_frame = ttk.Frame(self, padding="10")
        top_frame.pack(fill=tk.X, padx=10, pady=5)
        top_frame.columnconfigure(2, weight=1)

        # 请求方法选择
        method_label = ttk.Label(top_frame, text="请求方法:")
        method_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")

        methods = ["GET", "POST", "PUT", "DELETE"]
        method_menu = ttk.OptionMenu(
            top_frame, self.method_var, methods[0], *methods
        )
        method_menu.grid(row=0, column=1, padx=5, pady=5)

        # URL输入框(移除StringVar绑定,直接通过get()获取)
        url_label = ttk.Label(top_frame, text="请求URL:")
        url_label.grid(row=0, column=2, padx=5, pady=5, sticky="w")

        self.url_entry = ttk.Entry(
            top_frame, width=100
        )
        self.url_entry.grid(row=0, column=3, padx=5, pady=5, sticky="ew")
        top_frame.columnconfigure(3, weight=2)

        # 发送按钮
        send_btn = ttk.Button(
            top_frame, text="发送请求", command=self.send_request
        )
        send_btn.grid(row=0, column=4, padx=10, pady=5)

        # 中间请求体区域
        body_frame = ttk.LabelFrame(self, text="请求体(支持JSON格式化)", padding="10")
        body_frame.pack(fill=tk.X, padx=10, pady=5)
        body_frame.columnconfigure(0, weight=1)

        # 请求体文本框(无StringVar绑定)
        self.body_text = scrolledtext.ScrolledText(
            body_frame, wrap=tk.WORD, height=10
        )
        self.body_text.grid(row=0, column=0, sticky="nsew")

        # 格式化JSON按钮
        format_btn = ttk.Button(
            body_frame, text="格式化JSON", command=self.format_json
        )
        format_btn.grid(row=1, column=0, padx=5, pady=5, sticky="w")

        # 底部响应区域
        response_frame = ttk.LabelFrame(self, text="响应结果", padding="10")
        response_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        response_frame.rowconfigure(0, weight=1)
        response_frame.columnconfigure(0, weight=1)

        # 状态提示
        self.status_var = tk.StringVar(value="状态: 等待请求")
        status_label = ttk.Label(
            response_frame, textvariable=self.status_var, foreground="#333"
        )
        status_label.grid(row=1, column=0, padx=5, pady=2, sticky="w")

        # 响应内容文本框(保留高亮配置)
        self.response_text = scrolledtext.ScrolledText(
            response_frame, wrap=tk.WORD, state=tk.DISABLED, font=("Consolas", 10)
        )
        self.response_text.grid(row=0, column=0, sticky="nsew")

    def init_json_highlight_tags(self):
        """初始化高亮标签(仅给响应体文本框添加)"""
        for tag_name, color in self.json_tags.items():
            self.response_text.tag_configure(tag_name, foreground=color)

    def highlight_json(self, text_widget, json_content):
        """通用JSON高亮方法(仅用于响应体)"""
        text_widget.tag_remove("all", "1.0", tk.END)
        text_widget.delete("1.0", tk.END)
        text_widget.insert("1.0", json_content)

        try:
            parsed = json.loads(json_content)
            formatted = json.dumps(parsed, indent=2, ensure_ascii=False)
            text_widget.delete("1.0", tk.END)
            text_widget.insert("1.0", formatted)
            self._tag_json_elements(text_widget, formatted)
        except json.JSONDecodeError:
            pass

    def _tag_json_elements(self, text_widget, json_str):
        """递归标记JSON元素(内部辅助方法)"""

        patterns = [
            ("key", r'"([^"]+)"(?=\s*:)'),
            ("string", r'"([^"]*)"'),
            ("number", r'-?\d+(\.\d+)?([eE][+-]?\d+)?'),
            ("boolean", r'\b(true|false)\b'),
            ("null", r'\b(null)\b'),
            ("brace", r'[{}\[\]]'),
            ("colon", r':'),
            ("comma", r',')
        ]

        for tag_name, pattern in patterns:
            for match in re.finditer(pattern, json_str):
                start = "1.0 + {} chars".format(match.start())
                end = "1.0 + {} chars".format(match.end())
                text_widget.tag_add(tag_name, start, end)

    def format_json(self):
        """格式化JSON"""
        content = self.body_text.get("1.0", tk.END).strip()
        if not content:
            messagebox.showwarning("提示", "请求体为空,无需格式化")
            return

        try:
            json_data = json.loads(content)
            formatted_json = json.dumps(
                json_data, indent=2, ensure_ascii=False, sort_keys=True
            )
            self.body_text.delete("1.0", tk.END)
            self.body_text.insert("1.0", formatted_json)
        except json.JSONDecodeError as e:
            messagebox.showerror("JSON格式错误", f"无法解析JSON:\n{str(e)}")

    def send_request(self):
        """发送HTTP请求"""
        url = self.url_entry.get().strip()
        method = self.method_var.get()

        body = None
        if method in ["POST", "PUT"]:
            content = self.body_text.get("1.0", tk.END).strip()
            if content:
                try:
                    body = json.loads(content)
                except json.JSONDecodeError:
                    body = content

        try:
            self.status_var.set("状态: 正在请求...")
            self.update_idletasks()

            start_time = datetime.now()

            if method == "GET":
                response = requests.get(url, timeout=30)
            elif method == "POST":
                response = requests.post(
                    url, json=body if isinstance(body, dict) else None,
                    data=body if not isinstance(body, dict) else None,
                    timeout=30
                )
            elif method == "PUT":
                response = requests.put(
                    url, json=body if isinstance(body, dict) else None,
                    data=body if not isinstance(body, dict) else None,
                    timeout=30
                )
            else:
                response = requests.delete(url, timeout=30)

            duration = (datetime.now() - start_time).total_seconds()
            self.status_var.set(
                f"状态: 成功 | 状态码: {response.status_code} | 耗时: {duration:.2f}s"
            )
            self.show_response(response)

        except RequestException as e:
            self.status_var.set("状态: 请求失败")
            messagebox.showerror("请求错误", f"无法连接到URL:\n{str(e)}")
        except Exception as e:
            self.status_var.set("状态: 未知错误")
            messagebox.showerror("错误", f"发生异常:\n{str(e)}")

    def show_response(self, response):
        """显示响应结果(保留JSON高亮)"""
        self.response_text.config(state=tk.NORMAL)
        self.response_text.delete("1.0", tk.END)

        try:
            json_data = response.json()
            formatted_json = json.dumps(
                json_data, indent=2, ensure_ascii=False, sort_keys=True
            )
            self.highlight_json(self.response_text, formatted_json)
        except json.JSONDecodeError:
            self.response_text.insert(tk.END, response.text)

        self.response_text.config(state=tk.DISABLED)

    def destroy(self):
        super().destroy()


if __name__ == "__main__":
    app = RequestSimulator()
    app.mainloop()

在这里插入图片描述

自动贩卖机系统的Python实现通常会使用Tkinter库,这是一个轻量级的图形用户界面(GUI)工具包,适合用于创建简洁易用的桌面应用。在构建一个自动贩卖机模拟器时,你可以使用Tkinter来设计界面元素,如按钮、标签和文本框,代表商品选择、付款、找零等功能。 以下是基本的步骤和概念: 1. **导入库**:首先需要导入Tkinter模块以及任何其他必要的模块,如time(用于模拟延迟)或os(处理文件操作)。 ```python import tkinter as tk from tkinter import messagebox ``` 2. **创建窗口**:定义窗口的基本属性,如大小、标题等。 ```python root = tk.Tk() root.title("自动贩卖机") ``` 3. **构建界面**:创建各种控件,如`Button`代表商品选择,`Entry`作为金额输入,`Label`显示状态信息等。 ```python items = {} # 商品列表和价格 item_buttons = {} # 商品按钮 entry = tk.Entry(root) # 输入框 ``` 4. **事件绑定**:为按钮添加点击事件,比如选择商品后更新库存和总计,或者接收付款请求。 ```python def select_item(item): # 更新库存和总计 pass for item, price in items.items(): button = tk.Button(root, text=item, command=lambda item=item: select_item(item)) item_buttons[item] = button button.pack() ``` 5. **处理付款**:用户输入金额后,检查是否足够支付选定的商品,并进行找零。 6. **错误处理**:利用`try-except`处理可能的异常,例如金额不足或非法输入。 7. **退出程序**:在窗口关闭时执行清理操作。 8. **主循环**:启动Tkinter的事件循环。 ```python root.mainloop() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

像风一样的男人@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值