臭名昭著aTrust隔离计划1.臭名昭著aTrust隔离计划2.VPN原理与aTrust隔离网络实践3.docker-easyconnect到底做了什么4.TUN(tunnel-隧道-虚拟网卡)模式
个人项目
personal(个人展示)GitHub Actions 自动部署个人展示项目
基于Quartz搭建的个人博客1.Quartz个人博客使用教程2.使用 rsync 增量部署 Quartz 博客3.使用 GitHub Actions 自动部署 Quartz 博客5.域名绑定6.CDN加速7.Google 搜索收录排查:为什么关键词搜得到别人,却搜不到我的网站?Obsidian、双向链接与知识图谱
架构设计
分布式分布式事务RPC原理
旅行
行程攻略青岛三日游行程攻略
前端
NginxNginx配置与反向代理入门
Nodenpm与npx的区别
数据库
mysql01.MySQL基础语法与约束02.MySQL数据库类型03.MySQL多表查询04.MySQL 索引05.MySQL 事务06.MySQL 隔离级别07.MySQL MVCC08.MySQL 锁09.EXPLAIN10.慢查询与 SQL 优化
mysql面试题01.索引问题02.事务与隔离级别03.锁机制04.存储引擎与性能优化05.用户权限、字符集与备份恢复
mysql实战01.EXPLAIN实战02.测试环境菜单误删排查与恢复03.MySQL IN 详解
网络
网络安全1.无线监听网卡苹果M系列虚拟机安装Kali Linux教程3.kali怎么使用RTL8812AU4.kali基础命令
网络基础进程之间怎样通过网络传递数据
网址常用网址
中间键
esElasticsearch 入门
mq
RabbitMQRabbitMQ高级RabbitMQ基础
1. MQ 基础2. MQ 核心角色与代码对应3. MQ Consumer Group 与消费模式4. SOFAMQ 账户变更代码实践5. MQ 可靠性问题6. 消息幂等
redis缓存击穿、穿透与雪崩Redis 分布式锁Redis 缓存问题Redis 数据结构
AI
使用说明
第三方插件&技能简介Archify使用与安装指南geekgeekRun使用OfferFlow使用指南Ponytail使用指南Skills Manager使用指南
CodexCodex CLI与IDE区别及使用指南Codex Hook单独配置与提交通知Codex MCP安装与使用指南Codex第三方插件安装与使用指南
Agent开发0-学习路线1.LLM、Token、上下文窗口与模型参数2.大模型 API、请求参数与响应结构3.Spring AI ChatClient4.Prompt、System Prompt、Prompt 模板6.结构化输出、JSON Schema7.SSE 流式响应8.会话 ID、聊天记录、Redis9.超时、重试、限流、降级10.*完成可运行聊天接口11.Function Calling、Tool Calling 原理12.用 Java 方法定义 Tool13.工具参数设计和校验14.实现订单查询工具15.实现物流查询工具16.实现库存查询工具17.多个工具自动选择18.工具异常、超时、重试
diy主机
主机零件学习1.CPU2.主板3.内存4.显卡5.硬盘6.散热7.风扇8.机箱热门型号价格表
捡垃圾diy-13600kf+5060diy-14600kf+5070
English高频词汇英文基础语法简单句子音标
GitGit常用命令Sublime Merge 使用指南
Java
工具库Caffeine本地缓存Reactor教程
工作实践如何使用@Async线程池使用与排查线上服务 CPU 使用率过高排查压测下RPC接口大量失败排查记录
基础1.HashMap2.ConcurrentHashMap3.HashSet4.final5.static6.volatile7.AtomicInteger8.String动态代理反射锁与线程同步线程注解
面试题1.HashMap 存储在方法内是线程安全的吗2.ArrayList参数传递与引用重新赋值3.== 和 equals 的区别、hashcode4.重载和重写的区别5.String、StringBuffer、StringBuilder区别及使用场景6.接口和抽象类7.ArrayList 与 LinkedList 的区别和扩容机制8.HashMap 和 Hashtable 的区别及底层实现9.Object 和 Objects 的区别10.ThreadLocal的原理和使用场景11.字节码是什么及作用12.Java类加载器有哪些13.双亲委派模型14.Java异常体系15.GC是什么16.GC如何判断对象可以被回收
面试总结0.HR面试模板1.面试一2.面试二3.面试三笔试
网络与 IO(黑马程序员-纯理论)01-网络编程基础02-IO模型与零拷贝03-BIO04-NIO基础与缓冲区05-NIO通道与选择器06-AIO
juc00-目录01-进程与线程02-线程同步与通信03-并发设计模式04-Java内存模型05-CAS与原子类06-ThreadLocal07-阻塞队列08-线程池使用与原理09-任务调度10-ForkJoin与享元模式11-AQS12-ReentrantLock13-读写锁14-并发协作工具15-ConcurrentHashMap16-CopyOnWrite与同步容器17-SkipListMap18-非阻塞队列
juc(工作常见)Java并发编程三个重点拆解
jvm1. JVM运行时数据区
Spring1.Spring IoC、DI与构造方法注入CGLIB、Byte Buddy 与 Spring AOPSpring 常用注解详解Spring Bean 生命周期
Spring MVC异常处理机制
linux常用命令
mac快捷键终端常用操作
python
基础01.Python是什么,为什么要安装Python02.Python项目中.venv是什么03.Python基础语法
基础实战sql替换
HTTPXHRMS员工详情接口调用(Python HTTPX)
windowswindows激活

一、💡 一句话理解

核心结论

调用网页背后的接口,本质上是用 Python 按浏览器相同的请求方式、地址、请求头和参数发送 HTTP 请求。对这个 HRMS 人员详情接口,先从浏览器开发者工具确认实际请求,再用 httpx 做受权限控制的查询。

二、🧭 理论:它是什么

2.1 接口调用不是“爬页面”

网页通常是前端界面,数据则由后端接口返回。这个地址看起来是 HRMS 的员工详情查询接口:

http://platform.cic.inter/api/innernewprod-aboss-hrms/platform/api/aboss/hrms/staff/query-staff-detail

Python 不需要解析 HTML;它只需像浏览器一样发送 HTTP 请求,接收 JSON 响应,再提取需要的字段。

2.2 一个请求由什么组成

部分作用当前接口的状态
请求方法GET、POST 等,决定如何传数据待从浏览器确认
URL要访问的接口地址已知
请求头 HeadersCookie、Token、Content-Type 等身份与格式信息待确认
请求参数查询哪位员工的编号、工号等待确认
响应 JSON后端返回的数据或错误信息待实际查看

不要猜测请求方式或字段

接口名含 query 不代表一定是 GET。很多企业内部系统会使用 POST + JSON 查询;应以浏览器 Network 面板中实际请求为准。

三、⚙️ 理论:它是怎么工作的

3.1 浏览器和 Python 做的是同一件事

httpx.Client 适合持续调用同一系统:它能复用连接,并保存客户端级别的请求头和 Cookie。HTTPX 官方文档说明,它支持同步与异步调用、Cookie 持久化和连接复用。

3.2 鉴权与 CSRF

内网系统常见的身份方式有:

  • Cookie:浏览器登录后由服务端下发的会话标识。
  • Authorization: Bearer <token>:请求头携带访问令牌。
  • CSRF Token:网页为防止跨站请求伪造额外校验的令牌。

代码中不要硬编码真实 Cookie、Token 或人员数据;通过环境变量传入,并且仅使用自己被授权的账号。

3.3 读取与修改要分开

本篇接口名称是 query-staff-detail,按名称判断它应是读取用途,但这仍需以实际请求为准。

对于修改接口,必须先读取确认目标,再用明确的 POST、PUT 或 PATCH 调用;保存操作日志,并避免对非幂等写请求做自动重试。

四、🚀 实践:从准备到验证

4.1 前置准备

  1. 在已获授权的内网环境中登录 HRMS。
  2. 打开浏览器开发者工具的 Network(网络) 面板。
  3. 在网页里查询一名你有权限查看的测试员工。
  4. 找到 query-staff-detail 请求,记录以下信息:
    • Request Method;
    • Request Headers 中必需的 Content-Type、Cookie、Token、CSRF Token;
    • Payload 或 Query String 中的参数名;
    • 响应 JSON 的实际结构。
  5. 安装依赖:
python3 -m pip install httpx

当前待确认项

仅凭接口地址,无法可靠得知它是 GET 还是 POST,也不能确定员工标识字段到底叫 staffId、staffCode 还是其他名称。

4.2 可以拿来干什么

在确认请求规则后,可以:

  • 查询单个员工的详情;
  • 把响应中的必要字段导出为 JSON;
  • 为后续有权限的修改接口建立统一的超时、错误处理和审计框架。

下面代码中的 payload 是示意结构。请以浏览器 Network 面板的真实 Request Payload 替换,不能直接假设字段名。

# 查询参数示例:字段名必须以浏览器实际请求为准。
payload = {
    "staffId": "测试员工标识",
}

4.3 完整实践:代码、启动和验证

新建文件:query_staff_detail.py

"""受权限控制地查询 HRMS 员工详情接口。"""
 
import json
import os
from datetime import datetime, timezone
 
import httpx
 
 
# 已知的 HRMS 查询接口地址。
API_URL = (
    "http://platform.cic.inter/api/innernewprod-aboss-hrms/"
    "platform/api/aboss/hrms/staff/query-staff-detail"
)
 
# 必须以浏览器 Network 面板显示的 Request Method 为准。
REQUEST_METHOD = os.getenv("HRMS_REQUEST_METHOD", "POST").upper()
 
# 必须以浏览器实际 Payload 为准;staffId 仅是占位示例。
REQUEST_BODY = {
    "staffId": os.getenv("HRMS_STAFF_ID", "请填写测试员工标识"),
}
 
 
def build_headers() -> dict[str, str]:
    """从环境变量组装请求头,避免把敏感凭据写进代码。"""
    headers = {
        "Accept": "application/json, text/plain, */*",
        "Content-Type": "application/json",
    }
 
    # 仅在系统确实使用 Bearer Token 时设置此变量。
    token = os.getenv("HRMS_BEARER_TOKEN")
    if token:
        headers["Authorization"] = f"Bearer {token}"
 
    # 仅在系统确实使用 CSRF 校验时设置;请求头名称以实际请求为准。
    csrf_token = os.getenv("HRMS_CSRF_TOKEN")
    if csrf_token:
        headers["X-CSRF-Token"] = csrf_token
 
    return headers
 
 
def query_staff_detail() -> dict:
    """发送查询并返回 JSON;HTTP 状态异常或非 JSON 响应会明确报错。"""
    if REQUEST_BODY["staffId"] == "请填写测试员工标识":
        raise ValueError("请先设置 HRMS_STAFF_ID,并将请求体字段改为实际字段名。")
 
    # 显式设置连接和读取超时,避免请求长期挂起。
    timeout = httpx.Timeout(timeout=15.0, connect=5.0)
 
    # Cookie 只在系统需要且账号具备权限时传入。
    cookies = {}
    session_cookie = os.getenv("HRMS_SESSION_COOKIE")
    if session_cookie:
        # Cookie 名也必须以浏览器实际请求为准。
        cookies["SESSION"] = session_cookie
 
    with httpx.Client(
        timeout=timeout,
        headers=build_headers(),
        cookies=cookies,
        follow_redirects=False,
    ) as client:
        if REQUEST_METHOD == "GET":
            # GET 参数放在 URL Query String 中。
            response = client.get(API_URL, params=REQUEST_BODY)
        elif REQUEST_METHOD == "POST":
            # POST 查询参数通常以 JSON 请求体发送。
            response = client.post(API_URL, json=REQUEST_BODY)
        else:
            raise ValueError(
                f"暂不支持的请求方法:{REQUEST_METHOD};请按 Network 面板填写 GET 或 POST。"
            )
 
    # 4xx/5xx 会抛出异常,避免把业务错误当成正常结果。
    response.raise_for_status()
 
    try:
        result = response.json()
    except json.JSONDecodeError as error:
        raise RuntimeError(
            f"接口未返回 JSON,Content-Type={response.headers.get('content-type')}"
        ) from error
 
    # 只记录操作时间、HTTP 状态和顶层字段,不记录 Token、Cookie 或完整人员信息。
    audit = {
        "time": datetime.now(timezone.utc).isoformat(),
        "method": REQUEST_METHOD,
        "status_code": response.status_code,
        "top_level_keys": list(result.keys()) if isinstance(result, dict) else None,
    }
    print("查询审计:", json.dumps(audit, ensure_ascii=False))
 
    return result
 
 
if __name__ == "__main__":
    try:
        data = query_staff_detail()
        # 首次验证时仅打印格式化 JSON;确认字段后再按需导出。
        print(json.dumps(data, ensure_ascii=False, indent=2))
    except httpx.TimeoutException:
        print("请求超时:请确认已连接公司内网、地址可达,并检查超时设置。")
    except httpx.HTTPStatusError as error:
        print(
            f"接口返回错误:HTTP {error.response.status_code};"
            "请检查请求方法、权限、Cookie/Token、CSRF Token 和参数。"
        )
    except (ValueError, RuntimeError) as error:
        print(f"配置或响应处理错误:{error}")

运行前,在终端设置变量。下面的值都是占位符,必须替换为浏览器实际请求中的合法信息:

export HRMS_REQUEST_METHOD="POST"
export HRMS_STAFF_ID="测试员工标识"
export HRMS_BEARER_TOKEN="仅在系统使用 Bearer Token 时填写"
export HRMS_CSRF_TOKEN="仅在系统需要 CSRF Token 时填写"
export HRMS_SESSION_COOKIE="仅在系统需要 Cookie 时填写"
 
python3 query_staff_detail.py

验证成功时,终端会先输出一条不含敏感数据的查询审计记录,再输出接口返回的 JSON。

如果出现 401 或 403,通常是登录态、权限、Cookie、Token 或 CSRF Token 不完整;如果出现 422 或业务提示参数错误,则应逐项比对浏览器请求的字段名、类型和嵌套结构。

五、📌 总结

  • 接口调用的关键是复现已授权浏览器请求,不是解析网页。
  • 先在 Network 面板确认方法、请求头和参数,不猜字段。
  • httpx 适合这类企业内部 API 的查询和后续受控调用。
  • 凭据用环境变量保存,不写进源码、笔记或 Git。
  • 修改接口先查询核对目标;写操作要有审批、日志和小范围验证。

六、📚 官方资料