Grafana接入自定义JSON API:代理解决格式、鉴权与CORS难题
简介面向Grafana中需要接入Oracle与MongoDB数据的开发与运维人员资源是一款名为grafana-json-proxy的辅助代理程序。它围绕simpod-json-datasource插件工作通过Java实现JSON格式的数据转换与转发让Grafana得以连接并查询这两种数据库弥补官方数据源插件对Oracle/MongoDB支持不足的短板。这类需求常见于构建统一监控看板、整合异构数据源的场景适合有一定Java基础的运维或开发人员参考。资源包共26个文件包含7个Java源码、7个编译后的class文件、7个XML配置文件、2个YAML配置文件以及说明文档等整体大小约36KB工程采用Maven组织代码与配置分离其中Java源码可供阅读与二次开发XML负责依赖或映射配置YAML常用于描述Spring Boot或数据源参数清晰的注释与配置示例可降低接入门槛。目前已有160人浏览学习借助此包可掌握自定义JSON代理的开发思路理解Grafana插件与后端数据库的交互链路并为自己的监控系统快速搭建一套可扩展的异构数据接入方案。1. grafana-json-proxy一个被 Dashboard 逼出来的轻量代理做过监控可视化的人大多有这种经历Grafana 装好了Prometheus、MySQL、ClickHouse 都是现成的数据源填个地址就能出图。可一旦你的业务指标存在某个内部 API 里或者第三方系统只对外暴露一个 JSON 接口Grafana 就变成了一个摆设——不是不能接而是直接接入之后鉴权、CORS、响应格式这些坑会一个个冒出来。grafana-json-proxy 就是在这种场景下最实用的一层“翻译官”和“传话人”它站在 Grafana 和你的业务 API 之间替 Grafana 处理签名、拼参数、洗数据把任意 JSON 响应转换成 Grafana 认得的表格或时间序列结构。这个方案适合两类人。一类是刚接触 Grafana 的开发者想用 grafana-json-proxy 快速搭出一个能用的自定义数据源另一类是正在做监控平台或运维中台的工程师需要在不改动业务代码的前提下把一个内部 HTTP 服务平滑接入 Grafana并且后续还要叠加鉴权、缓存、限流。你会发现与其去折腾 Grafana 官方插件的配置不如花半小时在代理层做一次统一适配后面所有数据源都走这一条路逻辑清晰也不容易翻车。2. 为什么要自己写 JSON 代理格式、鉴权和 CORS 的三个边界2.1 Grafana 对数据源的“期待”查询模型不是你想的那样Grafana 的数据源模型本质上是协议化的。无论是 Prometheus 还是 MySQLGrafana 都会把一个 Panel 的查询拆成两类请求一类是查询请求带着from到to的时间范围、intervalMs的时间粒度以及你在 Query 编辑器里填的查询字符串另一类是元数据请求比如用于维度下拉框的搜索请求、用于命名规则的按键请求。你的 JSON API 如果只支持一个简单的getMetric?date2024-01-01那 Grafana 根本不知道该怎么把这个请求翻译过去。这就是 grafana-json-proxy 存在的第一个理由——格式翻译。它需要把 Grafana 的查询模型翻译成业务 API 能理解的参数再把业务 API 的响应翻译回 Grafana 能识别的结构。常见做法是把代理层做成一个薄转发服务接收 Grafana 的/api/query请求解析出查询目标转成实际接口的 URL Query 或 POST Body收到响应之后再按照 Grafana 定义的响应格式组装回去。以时序查询为例Grafana 期望的响应通常是这样的 JSON[ { target: metric_name, datapoints: [ [23.5, 1704060000000], [24.1, 1704063600000] ] } ]而在时序型 JSON 数据源插件里也可能要求按字段返回。[ { name: cpu_usage, fields: [ {name: time, type: time, values: [1704060000000, 1704063600000]}, {name: value, type: number, values: [23.5, 24.1]} ] } ]这两种格式的差异并不只是字段名不同前者是数组嵌套数组后者是列式存储结构。代理层至少要对接一种否则就算 Grafana 收到了数据也无法绘制曲线。我一般建议在代理端固定使用第二种列式格式因为它在处理多指标返回时比数组嵌套数组更直观也方便后续扩展维度字段。2.2 让 Grafana 直接连第三方 API 的“死结”在哪里不少人会问Grafana 的 JSON 数据源插件不是可以直接填 URL 吗是的能填但只能填一个固定的地址。实际工作中你会发现三个绕不过去的问题。第一是鉴权方式不匹配。你的内部系统可能是自定义的加密签名比如需要把时间戳和 token 做 HMAC 然后放进 Header可能是 OAuth2 的 client_credentials先换 token 再请求也可能用的是企业内部登录后的 Cookie。Grafana 插件本身只支持简单的 Basic Auth 或静态 Bearer Token复杂的签名逻辑根本没法在 UI 上配置。第二是CORS 限制。如果 Grafana 部署在另一台机器上浏览器发起的请求会直接打到你的 API 域名而这种跨域请求通常会被后端拦掉。要么去给后端加 CORS 白名单要么就得等代理来中转。前者涉及另一套系统的配置改动后者只在你自己的代理上增加一个 Access-Control-Allow-Origin 头就能解决。第三是字段语义不一致。业务 API 返回的可能是{data: {list: [{time: 2024-01-01 10:00, value: 12.3}]}}这种多层嵌套结构而 Grafana 需要的是扁平的时间序列。适配的工作量其实不小直接写在查询表达式里会非常痛苦远不如在代理端做一次递归解析。所以当你需要让 Grafana 稳定接入一个“不那么友好”的 HTTP 接口时自己写一个 JSON 代理就不再是可选项而是避免反复踩坑的捷径。不是 Grafana 不够用是它的插件机制默认了“接口已经适配好”这个前提。真实世界的接口很少满足这个前提。2.3 选型Python Flask vs Node.js Express vs Go net/http代理实现的语言选型跟团队熟悉度关系最大但从维护和部署角度看有几个维度值得比较维度Python / FlaskNode.js / ExpressGo / net/http上手成本低中中部署体积需要 Python 环境需要 Node 环境单二进制并发处理够用配合 gunicorn高高JSON 处理非常方便方便略繁琐适合场景接口不多、逻辑复杂接口多、快速迭代高并发、追求零依赖部署我自己的习惯是如果只代理两三个接口用 Python Flask 写代码短、易读、后续接手的人也不会有心理负担如果可能被十几个面板同时拉数据就换成 Node.js 或者 Go因为 Grafana 的刷新机制有时会同时发起很多并发请求Python 的同步 Flask 不加额外配置会阻塞。3. 本地搭建 grafana-json-proxy最小可运行代码与参数设置3.1 先搞定两个关键配置项Grafana 的 Query 请求和 JSON 数据源的响应契约在动手写代码之前需要先明确你在和谁打交道。这里的“谁”指的是 Grafana 侧的两个角色一个是数据源插件它负责把你在面板上的可视化查询转换成 HTTP 请求发给代理另一个是Grafana 的查询处理器它负责把代理返回的数据渲染成曲线。以最常见的 JSON 数据源插件为例Grafana 发出来的请求结构大约长这样{ queries: [ { refId: A, model: { target: cpu_used_percent, host: web-01, type: timeserie }, intervalMs: 60000, range: { from: 2024-01-01T00:00:00.000Z, to: 2024-01-01T01:00:00.000Z } } ] }注意这里的range字段包含了从和到的时间但它们的时区是 UTC。如果你的业务 API 接收的是本地时间的字符串格式代理层必须做一次时区换算。最常见的翻车点就是把 Grafana 传过来的 UTC 时间直接拼进 URL导致后端数据按本地时间查询时差了八个小时。代理收到这个请求后可以提取出其中的model和range然后重组为业务 API 的请求。比如业务 API 需要的参数是startTime、endTime和metric那代理就把range.from和range.to转成毫秒时间戳传给后端。针对响应格式代理层要规划好内部统一的 Schema。我习惯先定义成 Grafana JSON 数据源插件能识别的格式[ { columns: [ {text: time, type: time}, {text: value, type: number} ], rows: [ [1704060000000, 23.5], [1704063600000, 24.1] ] ] }columns描述列的类型rows是具体数据时间统一为毫秒级时间戳。这种格式的好处是直观、容易调试任何一步出错都可以在浏览器里直接看响应体。等业务跑通后再考虑切换成列式格式来减少响应体体积。3.2 写一个最少代码的 Flask 代理转发、改写请求和组装响应下面是一个能跑通的最小实现。假设业务 API 是一个简单的 GET 接口返回结构是{ code: 0, data: [ {timestamp: 2024-01-01 08:00:00, value: 12.3}, {timestamp: 2024-01-01 08:05:00, value: 13.7} ] }代理要做的四件事接收 Grafana 请求、提取查询参数、请求业务 API、按 Grafana 期望的结构返回。import time import calendar import requests from flask import Flask, request, jsonify from datetime import datetime app Flask(__name__) # 业务 API 地址改成你自己的 BUSINESS_API http://10.0.0.5:8080/metrics def local_to_ms(local_dt_str): 把 2024-01-01 08:00:00 转成毫秒时间戳假设业务系统使用东八区 dt datetime.strptime(local_dt_str, %Y-%m-%d %H:%M:%S) return int(calendar.timegm(dt.utctimetuple()) * 1000) def parse_ts_range(range_obj): 把 Grafana 传来的 range 对象转成毫秒时间戳 from_ms int(datetime.fromisoformat(range_obj[from].replace(Z, 00:00)).timestamp() * 1000) to_ms int(datetime.fromisoformat(range_obj[to].replace(Z, 00:00)).timestamp() * 1000) return from_ms, to_ms app.route(/api/query, methods[POST]) def query(): payload request.get_json() results [] for q in payload.get(queries, []): model q.get(model, {}) metric model.get(target) host model.get(host, ) interval_ms q.get(intervalMs, 60000) from_ms, to_ms parse_ts_range(q[range]) # 组装业务 API 请求 params { metric: metric, host: host, start: from_ms, end: to_ms } # 超时设置很重要防止上游接口卡死拖垮 Grafana resp requests.get(BUSINESS_API, paramsparams, timeout5) data resp.json().get(data, []) rows [] for item in data: ts_ms local_to_ms(item[timestamp]) if interval_ms 0: # 可选按 interval 对齐时间戳保证曲线横轴均匀 ts_ms int(ts_ms / interval_ms) * interval_ms rows.append([ts_ms, item[value]]) results.append({ target: f{metric} ({host}) if host else metric, columns: [ {text: time, type: time}, {text: value, type: number} ], rows: rows }) return jsonify(results) if __name__ __main__: app.run(host0.0.0.0, port9200, debugFalse)这里的代码做了几件关键的事第一个是parse_ts_range它负责把 Grafana 传来的 ISO 字符串解析成毫秒时间戳。如果不做这一步直接把字符串透传给业务 API很多后端会因为格式不识别而返回空数据。第二个是local_to_ms它把业务系统的本地时间字符串转换成毫秒时间戳。这里我硬编码了东八区假设实际项目中建议从配置文件读取时区偏移因为不同业务系统的存储时区经常不统一。第三个值得注意的地方是intervalMs对齐。Grafana 会根据面板的时间范围自动计算查询粒度如果你直接把原始数据返回Grafana 可能面临数据点过多导致渲染卡顿的问题。这里做了简单的整除对齐能显著减少数据点数量。运行方式是FLASK_ENVproduction python app.py生产环境不要用app.run改用 gunicorn 多进程跑防止单个 Grafana 刷新动作触发多个并发请求而阻塞。gunicorn -w 4 -b 0.0.0.0:9200 app:app-w 4表示启动 4 个 worker 进程-b指定服务端口一般 9200 或 8081 都行只要别和 Grafana 自身的端口冲突。3.3 代理层的三个必调参数代码能跑通只是第一步实际使用中有三个参数直接影响排查问题的效率和系统稳定性。第一个是timeout。Grafana 对每个查询请求都有自身的超时限制默认是 30 秒部分版本可调。如果你的业务 API 偶尔响应慢代理端的 timeout 要小于 Grafana 的超时比如设置成 10 秒这样 Grafana 收到的是代理的 500 或 504而不是无限等待。超时报文建议带上custom_headers让 Grafana 面板直接显示提示信息否则前端只能看到一个泛化的 bad gateway。第二个是日志级别与访问日志。代理层至少要把query、params、response_status打印出来。我习惯在转发前后各打一条日志前一条记录 Grafana 原始请求后一条记录业务 API 的耗时和返回长度。这样当你看到一个曲线图出现断点或毛刺时可以先查代理日志而不是直接去查 Grafana 和业务系统两边。第三个是时间对齐的粒度选择。intervalMs是从 Grafana 传来的但在面板上用户可能把最小时间间隔调得很小导致后端被频繁请求。代理端可以对这个值做一个下限限制比如小于 10 秒的统一按 10 秒处理。这里要小心不能一刀切否则放大长时间范围查询时Grafana 会拿到过多降采样后的数据曲线会变“方”。4. 配置 Grafana 对接代理从 Data Source 到 Panel 的完整链路4.1 新建数据源URL、Access 和 Header 的真实配置逻辑Grafana 侧的操作其实比想象中简单。进入 Connections - Data Sources - Add data source选择你的 JSON 数据源插件类型。注意不要选成 Prometheus 或 InfluxDB它们的请求路径是固定的/api/v1/query_range你临时写的代理大概率不兼容。这里只填三项必要配置URL填http://你的代理IP:9200如果 Grafana 和代理在同一台机器可以用http://localhost:9200。Access选 Server。这是最容易忽略的一项。默认的 Browser 模式会由浏览器直接发起请求到代理地址一旦 Grafana 部署在内网、用户通过域名访问浏览器很可能无法解析你的内网 IP导致页面能打开但数据一直为空。HTTP Headers如果代理要做简单鉴权在这里加一个Authorization: Bearer xxx。代理端再校验这个 Header就能挡住外部直接访问。这里要说一句Access 模式选 Server 意味着 Grafana 后端来发请求浏览器的 CORS 限制就不会作用到 Grafana 和代理之间。很多人卡在“代理返回 200 但面板没有数据”的坑里有相当大比例就是这个配置选错了。4.2 面板上的 Query 写法怎么让代理侧拿到可用的 model面板创建时Query 编辑器部分会显示数据源插件自定义的表单。我的经验是使用target字段作为主要指标名用其他字段做维度过滤。以 CPU 监控为例可以这样写字段值说明targetcpu_used_percent指标名对应业务 API 的 metric 参数hostweb-01过滤条件对应代理代码里的 model.hosttypetimeserie固定写死代理不用管插件会用如果你用的 JSON 数据源插件支持更灵活的 JSON 配置可以把多条件直接写进一个 JSON 块里例如{ metric: cpu_used_percent, host: web-01, agg: avg }代理端解析时直接用model.agg来决定是否做聚合。这样比把每个字段都摊到 UI 上要灵活因为你每新增一个条件就得在代理代码里加一段解析逻辑而 JSON 块的方式是透传的后端接口只需要把它当作参数原样接收。4.3 从代理到面板之间v8 到 v10 的兼容差异Grafana 版本更迭中JSON 数据源插件的请求模型有轻微变化。v9 之后插件默认在payload中加入了scopedVars和search相关字段这对代理转发是不影响的功能。但有一个点容易翻车早期版本的插件使用/query作为查询路径后来部分插件改为/api/query。如果你的 Grafana 版本较新而代理端监听的还是/query会看到数据源配置测试通过但面板查询永远 404。最好的策略是让代理同时兼容两个路径app.route(/api/query, methods[POST]) app.route(/query, methods[POST]) def query_alias(): ...同样的逻辑也适用于search接口它用于下拉框自动补全。如果插件不支持搜索面板填指标名时只能手动输入不影响出图但体验会差一些。让代理实现一个简单的/search接口返回固定列表能省去很多手动输入错误。4.4 让代理跑在公网前的 Nginx 反代配置如果你的 Grafana 是跨部门访问代理通常不能直接暴露裸端口。常见的做法是在代理前面套一层 Nginx做路径转发、超时和缓冲设置location /json-proxy/ { proxy_pass http://127.0.0.1:9200/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 5s; proxy_read_timeout 15s; proxy_buffering off; }proxy_pass末尾带/代表把/json-proxy/后面的路径原样转发到代理服务的根路径这样 Grafana 的 URL 可以填http://你的域名/json-proxy后面/api/query会自动拼上。proxy_buffering off是为了让大响应体也能迅速传给 Grafana否则 Nginx 缓冲可能导致 Grafana 长时间拿不到数据而显示加载中。如果代理需要暴露在公网建议在同一层 Nginx 上加一个简单的 IP 白名单或 Basic Auth避免任何人都能调用你的代理端口去探测内网 API。5. 代理落地后的排查与避坑4 个常被拉出来祭天的现场5.1 面板显示 No data 但代理日志有请求进来这个现象的特点是 Grafana 发出了请求代理也转发到了业务 API业务 API 也返回了数据但最终 Grafana 面板上一片空白。出现这种现象排查方向往往不是“数据有没有”而是“数据长什么样”。真正的原因是响应格式不满足 Grafana 插件的严格要求。比如我把columns里的type写成了number但实际上rows里放的是字符串数字又比如时间戳用了秒而不是毫秒Grafana 会把这个值当成毫秒来解析导致时间轴显示在 1970 年附近面板自然就查不到可见范围的数据。解决办法是在调试时先绕过 Grafana直接模拟它的请求curl -X POST http://localhost:9200/api/query \ -H Content-Type: application/json \ -d { queries: [{ refId: A, model: {target: cpu_used_percent, host: web-01}, intervalMs: 60000, range: { from: 2024-01-01T00:00:00.000Z, to: 2024-01-01T01:00:00.000Z } }] }然后检查返回的rows里时间戳是不是毫秒、数值是不是数字而不是字符串。这个 curl 命令以后会频繁用到建议存成脚本每次改代理代码后先跑一遍再切到 Grafana 面板。5.2 代理偶发 500业务 API 正常但 Grafana 刷几次挂一次这个坑我踩了很多次才彻底理解不是代理代码逻辑有问题而是 Grafana 面板在加载时会对一个 Panel 发起多个查询请求而每个请求都会触发一次业务 API 调用。如果业务 API 没有限流一旦有多个用户同时打开 Dashboard代理和业务 API 的压力会突然上来。表现出来的症状就是时好时坏、刷新多次才能出一次图。解决办法是给代理加最基本的并发保护。一种做法是引入内存级限流from threading import Lock lock Lock() last_request_ts {} app.route(/api/query, methods[POST]) def query_with_limit(): metric request.get_json()[queries][0][model][target] with lock: now time.time() if metric in last_request_ts and now - last_request_ts[metric] 1: return jsonify({error: too many requests}), 429 last_request_ts[metric] now return query()这样同一个指标每秒只允许一次真实请求。代价是 Grafana 快速刷新时部分请求会直接返回 429面板可能会短暂显示警告。但比起把后端打挂这个折衷是可以接受的。5.3 时区差八个小时被 UTC 字符和本地时间互相折磨这是排障耗时最长的问题。Grafana 面板上设置了 Asia/Shanghai展示的时间也确实是北京时间但曲线上的数据点和对不上总是整体平移了几个小时差值恰好是完整的八小时。原因出在业务 API 返回的时间字符串不是 UTC而是东八区本地时间。我在代理代码里转换时如果直接把这个字符串当 UTC 转时间戳转出来的值会比真实时间少八小时Grafana 拿到这个少八小时的时间戳按面板时区展示后看起来就往后挪了八小时。正确的做法是先明确业务系统存储的是什么时区如果是本地时间就按本地时区解析再转 UTC 时间戳。此前代码中的local_to_ms函数本质上就是做这件事只是时区偏移需要从配置读取。另一个隐蔽的陷阱是 Grafana 的range.from和range.to在近实时场景里末尾会有一个now的微调偏移比如to实际是“当前时间加一分钟”。如果你的代理对to做了闭区间包含可能多取到未来的数据点导致曲线的最后一段出现突刺。处理方式是对to做一次min(to, 当前时间)的钳制。5.4 上游 API 返回了很多字段你只需要两个业务 API 通常不会只给你返回时间戳和指标值它可能会附带一堆其他字段甚至有些字段结构不固定。代理层如果直接把这些字段平铺到rows里Grafana 只能忽略多余字段但解析时间会变长并且如果字段里包含 null 值某些插件会对null处理得比较笨拙。这里建议在代理层做字段白名单过滤只保留time和value。遇到多维度指标可以拆成多个序列每个序列一个 target 名称。例如cpu_used_percent加上host维度最终返回的target可以是cpu_used_percent (web-01)。这样 Grafana 面板的 Legend 可以自动区分多台机器而不用手工去写复杂的别名规则。6. 进阶从能用到好用给 grafana-json-proxy 加上缓存、鉴权和更细的控制当代理稳定跑了一段时间后你大概率会想再提升一点体验。我一般会按顺序做三件事加缓存、加鉴权、加查询改写。6.1 一个简单的 TTL 内存缓存Grafana 面板的刷新频率往往远高于业务数据的更新频率。比如你的业务 API 每分钟才更新一次面板却每 10 秒刷新一次。这种情况下代理就可以做成缓存模式同一指标同一时间范围的请求在 TTL 内命中缓存就直接返回减少业务系统的压力。import functools import threading cache_lock threading.Lock() cache_store {} def ttl_cache(ttl_seconds30): def decorator(func): functools.wraps(func) def wrapper(query_key, *args, **kwargs): now time.time() with cache_lock: cached cache_store.get(query_key) if cached and now - cached[ts] ttl_seconds: return cached[data] result func(query_key, *args, **kwargs) with cache_lock: cache_store[query_key] {ts: now, data: result} return result return wrapper return decorator注意这个缓存是对内存的进程重启即失效。如果需要跨进程共享或持久化可以用 Redis但大多数场景内存足够。TTL 取值要与业务数据更新频率同步设置太短没效果设置太长会造成面板数据明显滞后。6.2 给代理加上 Basic Auth 和 API Key 两层校验代理一旦暴露在局域网或公网任何人都可以构造请求去访问业务 API。给代理加一层简单鉴权非常有必要。我通常建议用两种方式配合Nginx 层限制来源 IP代理层校验一个静态 API Key。from functools import wraps from flask import abort, request def require_api_key(f): wraps(f) def wrapper(*args, **kwargs): api_key request.headers.get(X-API-Key) if api_key and api_key your-static-key: return f(*args, **kwargs) abort(401) return wrapper在需要保护的接口上加上require_api_key然后 Grafana 数据源的 Header 里配置X-API-Key: your-static-key。Grafana 会把 Header 附加到每个请求上二者就能对上。6.3 查询改写同一个指标分组和聚合参数让后端一次算完最后一块值得投入的功能是查询改写。Grafana 面板上用户可能同时想看均值、最大值和 PV 总量业务 API 如果只支持单指标的原始数据点代理就需要自己聚合。聚合逻辑尽量压给后端前提是后端支持如果后端不支持代理层做简单的均值、最大、最小聚合也够用。def aggregate(rows, agg_type): if agg_type avg: ... elif agg_type max: ... return result这块代码不复杂但要注意聚合的时间窗口应与 Grafana 的intervalMs对齐否则同一个指标不同 Panel 看到的聚合结果可能不同面板之间对不上。6.4 验证方法和工作习惯代理部署后我会用一个固定的验证流程先 curl 代理接口确认返回数据正确再用 Grafana 的一个新面板做最小化查询确认出图最后打开浏览器开发者工具看 Network 面板里数据源请求的耗时和报文状态码。如果出现耗时超过 1 秒的请求优先检查业务 API 响应时间和代理日志里的时间分布。我的个人习惯是把代理的配置项集中到一个config.yaml或环境变量文件里包括业务 API 地址、超时时间、TTL、时区偏移。每次要调整只改配置不改代码。这样一个 grafana-json-proxy 就能从一次性脚本变成长期维护的监控基础设施团队里其他人接手时也不至于一脸懵。这个方向确实值得投入希望这篇笔记能帮到你。本文还有配套的精品资源点击获取

相关新闻

佳宜仓库管理软件v3.35企业版绿色版部署、避坑与数据迁移指南

佳宜仓库管理软件v3.35企业版绿色版部署、避坑与数据迁移指南

简介:佳宜仓库管理软件v3.35(企业版)是一款面向中小型仓储与门店库房的绿色免安装管理工具,适合仓管员、个体经营者以及正在从手工台账向信息化过渡的初学者使用。它聚焦日常出入库登记、库存查询等基础操作场景,旨在解…

2026/10/11 9:42:47 阅读更多 →
GAMMA InSAR命令行处理全流程:从SLC到形变图的10步硬核实践

GAMMA InSAR命令行处理全流程:从SLC到形变图的10步硬核实践

简介:本资源是一份面向遥感科学、测绘工程及地球物理领域研究者与高年级研究生的GAMMA软件InSAR处理技术详解课件,聚焦合成孔径雷达干涉测量的核心流程与实操要点。课件系统梳理了从多视处理、SLC配准、干涉纹图生成,到基线估算、平地效应去除…

2026/10/11 9:41:46 阅读更多 →
汉字简体繁体对照表数据库设计:从字符集到词级转换的完整方案

汉字简体繁体对照表数据库设计:从字符集到词级转换的完整方案

简介:《汉字简体繁体参照表》是一份面向开发者、数据分析师及语言处理学习者的实用数据集,收录约4792条简体与繁体汉字映射关系,可支撑多语言软件简繁切换、文本预处理、数据清洗与学术研究等场景。资源包共4个文件,压缩包仅162KB…

2026/10/11 9:41:46 阅读更多 →

最新新闻

批处理执行模型与避坑实战:变量展开、括号块与for /f解析

批处理执行模型与避坑实战:变量展开、括号块与for /f解析

简介:《Windows命令行(批处理)语法全解》是一份面向Windows运维人员、开发者和脚本初学者的批处理语法参考文档。文档系统介绍了Command Shell与PowerShell两种命令行环境,不仅讲解如何编写.bat批处理文件,还深入分析了命令重定向运算符、for…

2026/10/11 10:27:11 阅读更多 →
AI编程助手:Aider使用手册(中文版)——TaoToken统一Key接入与本地验证

AI编程助手:Aider使用手册(中文版)——TaoToken统一Key接入与本地验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:27:11 阅读更多 →
ApplyPilot两种玩法全解:0元用免费Gemini也能完成AI改简历与自动求职

ApplyPilot两种玩法全解:0元用免费Gemini也能完成AI改简历与自动求职

【免费下载链接】ApplyPilot AI agent that applies to jobs for you. Any site. Any form. 项目地址: https://gitcode.com/gh_mirrors/ap/ApplyPilot 点击查看 免费下载 ApplyPilot 是一个开源的 AI 自动求职 Agent,口号是“任意网站、任意表单都能帮…

2026/10/11 10:27:11 阅读更多 →
WordPress 在线参考文档:用 TaoToken 统一 Key 打通 AI 辅助写作与文档生成

WordPress 在线参考文档:用 TaoToken 统一 Key 打通 AI 辅助写作与文档生成

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:27:11 阅读更多 →
越改越废!2026论文最大误区:盲目润色!正确改稿逻辑终于懂了|PaperXie救命✨

越改越废!2026论文最大误区:盲目润色!正确改稿逻辑终于懂了|PaperXie救命✨

有没有发现一个诡异的现象: 初稿明明还行,越用AI润色、越手动修改,论文越烂! 逻辑崩了、文风割裂、深度更浅、AI痕迹爆表、查重忽高忽低…… 很多2026毕业生最后论文翻车,不是写得差,是改错了&#xff0…

2026/10/11 10:27:11 阅读更多 →
从0到1搭建内容分发体系:2026自媒体矩阵运营全攻略

从0到1搭建内容分发体系:2026自媒体矩阵运营全攻略

流量逻辑已彻底更迭,单账号单打独斗的运营模式红利消退。当下多数自媒体创作者、中小品牌布局多账号矩阵时,普遍面临内容同质化、违规踩坑、数据难溯源、人力成本高、转化效率低等问题。专业的内容分发体系绝非简单一键转载内容,而是围绕用户…

2026/10/11 10:26:10 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →