【实现curl请求与python脚本的转化】

实现curl请求与python脚本的转化

  • 成果
  • 实现思路
  • 使用的技术
  • 后端处理逻辑
  • 主运行函数
  • 工具相关函数
  • 核心业务函数
  • 效果呈现
    • 转化get请求
    • post请求
    • put请求
  • 完整代码

成果

什么都不用说,先上效果截图
【实现curl请求与python脚本的转化】_第1张图片
上图是实现的最终效果,是不是觉得很cool

实现思路

	1.实现一个可视化页面来接收用户输入curl请求
	2.将curl请求传给后端进行数据处理
	3.将处理好的数据再返回给前端页面

使用的技术

	pywebio
	yapf

后端处理逻辑

1.通过浏览器F12复制curl请求
2.拿到curl请求内容,针对curl请求去做关键数据的转化
3.自定义一套python脚本模板
4.动态替换python脚本模板中的动态参数

主运行函数

def run():
    with use_scope("index", clear=True):
        put_row([put_text("测试常用调试工具").style(title_style)])
        show_curl_2_python()

工具相关函数

def clear_case(file_name):
    if os.path.exists(file_name):
        os.remove(file_name)


def write_to_file(file_name, data):
    with open(file_name, mode="w", encoding="utf-8") as f:
        f.write(data)


def read_file(file_name):
    if os.path.exists(file_name):
        with open(file_name, mode="r", encoding="utf-8") as f:
            data_str = f.read()
            # print(data_str)
        return data_str
    else:
        return "请输入数据,再进行操作"

核心业务函数

@use_scope("request", clear=True)
def show_curl_2_python():
    put_row(
        [
            None,
            put_column([
                put_html("
"
), put_text("复制curl请求: 打开浏览器 --> F12--> 选中请求 --> copy --> Copy as cURL(bash)").style(title_style), put_text("请输入curl请求:"), put_button("转化", onclick=show_curl_to_python_result), put_textarea(name="curl_data", rows=40, value="", code={ 'mode': "curl", 'theme': 'darcula' }) ], size="50px 50px 50px 50px 100%") , None, put_column([ put_html("
"
), None, None, put_text("转化为python脚本后:"), put_textarea(name="python_data", rows=40, value="", code={ 'mode': "python", 'theme': 'darcula' }) ], size="50px 50px 50px 50px 100%") , None ], size="20px 48% 4% 48% 20px" ) @use_scope("request", clear=False) def show_curl_to_python_result(): curl_to_python() pin.pin_update("python_data", value=read_file(files["py_template"])) def curl_to_python(): try: curl_data = pin.pin.curl_data # print(curl_data) curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S) curl_result_list = re.findall(curl_re_expression, curl_data) # print(curl_result_list) if not curl_result_list: for file_name in files.values(): clear_case(file_name) if curl_result_list: curl_result = curl_result_list[0] url_re_expression = re.compile("(http.*?)'", re.S) url_result_list = re.findall(url_re_expression, curl_result) url = url_result_list[0] headers_re_expression = re.compile("-H '(.*?)'", re.S) headers_result_list = re.findall(headers_re_expression, curl_result) # print(headers_result_list) headers = {} for header_str in headers_result_list: if ":" in header_str: key = header_str.replace(" ", "").split(":")[0] value = header_str.replace(" ", "").split(":")[1] headers[key] = value # print(headers) method_re_expression = re.compile("-X '(.*?)'", re.S) # print(method_re_expression) method_result_list = re.findall(method_re_expression, curl_result) # print(method_result_list) content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S) content_type_result_list = re.findall(content_type_re_expression, curl_result) # print(content_type_result_list) data = None method = None if not method_result_list and not content_type_result_list: method = "get" if method_result_list: method = str(method_result_list[0]).lower() if content_type_result_list: # print(method) if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]: if not method: method = "post" # print(method) if "application" in content_type_result_list[0]: data_re_expression = re.compile("--data-raw '(.*?)'", re.S) data_result_list = re.findall(data_re_expression, curl_result) # print(data_result_list) if data_result_list: data = json.loads(data_result_list[0]) if "multipart" in content_type_result_list[0]: data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S) data_result_list = re.findall(data_re_expression, curl_result) if data_result_list: data = data_result_list[0] py_json_template = """import requests headers = {{headers}} json_data = {{data}} response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False) print(response.text) """ py_template = """import requests headers = {{headers}} data = '{{data}}' response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False) print(response.text) """ if data and (isinstance(data, dict) or isinstance(data, list)): py_template = py_json_template.replace("{{headers}}", str(headers)).replace( "{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url) elif data and isinstance(data, str): py_template = py_template.replace("{{headers}}", str(headers)).replace( "{{data}}", data).replace("{{method}}", method).replace("{{url}}", url) else: # print("我执行了吗") py_template = str(py_template).replace("{{headers}}", str(headers)).replace( "data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace( 'data=str(data).encode("utf-8"), ', "") py_template = str(FormatCode(py_template)[0]) space_re_expression = re.compile("(:\n\s*?)'", re.S) space_result_list = re.findall(space_re_expression, py_template) # print(space_result_list) for space in space_result_list: # print(space) py_template = py_template.replace(space, ": ") # print(py_template) write_to_file("py_template.py", py_template) # print("我执行到底了") except: write_to_file("py_template.py", "curl请求格式错误,请重新复制")

效果呈现

使用的接口地址
http://httpbin.org/

转化get请求

curl

curl 'http://httpbin.org/get' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.get('http://httpbin.org/get',
                        headers=headers,
                        verify=False)

print(response.text)

【实现curl请求与python脚本的转化】_第2张图片

post请求

curl

curl 'http://httpbin.org/post' \
  -X 'POST' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Origin: http://httpbin.org' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '0',
    'Origin': 'http',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.post('http://httpbin.org/post',
                         headers=headers,
                         verify=False)

print(response.text)

【实现curl请求与python脚本的转化】_第3张图片

put请求

curl

curl 'http://httpbin.org/put' \
  -X 'PUT' \
  -H 'Accept-Language: zh-CN,zh;q=0.9' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'Origin: http://httpbin.org' \
  -H 'Pragma: no-cache' \
  -H 'Referer: http://httpbin.org/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
  -H 'accept: application/json' \
  --compressed \
  --insecure

python

import requests

headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Length': '0',
    'Origin': 'http',
    'Pragma': 'no-cache',
    'Referer': 'http',
    'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
    'accept': 'application/json'
}

response = requests.put('http://httpbin.org/put',
                        headers=headers,
                        verify=False)

print(response.text)

【实现curl请求与python脚本的转化】_第4张图片

完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Copyright ©  版权所有
# @Time    : 2022/11/16 12:01
# @Author  : 胡浩浩
# @Email   : [email protected]
# @File    : curl2python.py
# @IDE     : PyCharm
# @description :
import json
import os
import re

from pywebio import *
from pywebio.output import *
from screeninfo import get_monitors
from pywebio.pin import put_textarea
from pywebio.platform.tornado_http import start_server
from ruamel import yaml
from yapf.yapflib.yapf_api import FormatCode

css = """
.container {
    margin-top: 0;
    max-width: 100%;
}
.CodeMirror {
    font-size: 13px;
    width: {{width}};
    overflow: scroll;
}
"""

title_style = """
color: red;
"""
code_mirror_width = str(get_monitors()[0].width / 2)

css = css.replace("{{width}}", code_mirror_width + "px")
config(title="curl2python", theme="minty", css_style=css)
files = {
    "py_template": "py_template.py",
}


def clear_case(file_name):
    if os.path.exists(file_name):
        os.remove(file_name)


def write_to_file(file_name, data):
    with open(file_name, mode="w", encoding="utf-8") as f:
        f.write(data)


def read_file(file_name):
    if os.path.exists(file_name):
        with open(file_name, mode="r", encoding="utf-8") as f:
            data_str = f.read()
            # print(data_str)
        return data_str
    else:
        return "请输入数据,再进行操作"


@use_scope("request", clear=True)
def show_curl_2_python():
    put_row(
        [
            put_column([
                put_html("
"
), put_text("复制curl请求: 打开浏览器 --> F12--> 选中请求 --> copy --> Copy as cURL(bash)").style(title_style), put_text("请输入curl请求:"), put_button("转化", onclick=show_curl_to_python_result), put_textarea(name="curl_data", rows=40, value="", code={ 'mode': "curl", 'theme': 'darcula' }) ], size="50px 50px 50px 50px 100%"), None, put_column([ put_html("
"
), None, None, put_text("转化为python脚本后:"), put_textarea(name="python_data", rows=40, value="", code={ 'mode': "python", 'theme': 'darcula' }) ], size="50px 50px 50px 50px 100%") , None ], size="48% 4% 48% 20px" ) @use_scope("request", clear=False) def show_curl_to_python_result(): curl_to_python() pin.pin_update("python_data", value=read_file(files["py_template"])) def curl_to_python(): try: curl_data = pin.pin.curl_data # print(curl_data) curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S) curl_result_list = re.findall(curl_re_expression, curl_data) # print(curl_result_list) if not curl_result_list: for file_name in files.values(): clear_case(file_name) if curl_result_list: curl_result = curl_result_list[0] url_re_expression = re.compile("(http.*?)'", re.S) url_result_list = re.findall(url_re_expression, curl_result) url = url_result_list[0] headers_re_expression = re.compile("-H '(.*?)'", re.S) headers_result_list = re.findall(headers_re_expression, curl_result) # print(headers_result_list) headers = {} for header_str in headers_result_list: if ":" in header_str: key = header_str.replace(" ", "").split(":")[0] value = header_str.replace(" ", "").split(":")[1] headers[key] = value # print(headers) method_re_expression = re.compile("-X '(.*?)'", re.S) # print(method_re_expression) method_result_list = re.findall(method_re_expression, curl_result) # print(method_result_list) content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S) content_type_result_list = re.findall(content_type_re_expression, curl_result) # print(content_type_result_list) data = None method = None if not method_result_list and not content_type_result_list: method = "get" if method_result_list: method = str(method_result_list[0]).lower() if content_type_result_list: # print(method) if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]: if not method: method = "post" # print(method) if "application" in content_type_result_list[0]: data_re_expression = re.compile("--data-raw '(.*?)'", re.S) data_result_list = re.findall(data_re_expression, curl_result) # print(data_result_list) if data_result_list: data = json.loads(data_result_list[0]) if "multipart" in content_type_result_list[0]: data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S) data_result_list = re.findall(data_re_expression, curl_result) if data_result_list: data = data_result_list[0] py_json_template = """import requests headers = {{headers}} json_data = {{data}} response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False) print(response.text) """ py_template = """import requests headers = {{headers}} data = '{{data}}' response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False) print(response.text) """ if data and (isinstance(data, dict) or isinstance(data, list)): py_template = py_json_template.replace("{{headers}}", str(headers)).replace( "{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url) elif data and isinstance(data, str): py_template = py_template.replace("{{headers}}", str(headers)).replace( "{{data}}", data).replace("{{method}}", method).replace("{{url}}", url) else: # print("我执行了吗") py_template = str(py_template).replace("{{headers}}", str(headers)).replace( "data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace( 'data=str(data).encode("utf-8"), ', "") py_template = str(FormatCode(py_template)[0]) space_re_expression = re.compile("(:\n\s*?)'", re.S) space_result_list = re.findall(space_re_expression, py_template) # print(space_result_list) for space in space_result_list: # print(space) py_template = py_template.replace(space, ": ") # print(py_template) write_to_file("py_template.py", py_template) # print("我执行到底了") except: write_to_file("py_template.py", "curl请求格式错误,请重新复制") def run(): with use_scope("index", clear=True): put_row([put_text("测试常用调试工具").style(title_style)]) show_curl_2_python() if __name__ == '__main__': for file_name in files.values(): clear_case(file_name) start_server(run, port=8897)

你可能感兴趣的:(常用工具,python,web)