小爱音箱开源固件技术重构:从封闭系统到智能家居控制中心的深度改造
2026/8/7 18:04:09
采购与招标item_search接口(常见官方命名cgzb.item_search)是面向政府采购、企业招标、工程采购等场景的多维度招标采购项目检索接口,支持按关键词、地区、采购类型、预算区间、发布时间等条件筛选项目列表,分页返回结构化基础数据,可联动item_get接口获取项目详情,适配商机监控、采购数据分析、投标决策等核心业务。该接口采用HTTPS+API Key/Secret 签名认证,支持 JSON/XML 双格式返回,具备数据合规性强、筛选维度精准、权限分级明确的特点。本攻略从接口认知、权限准备、实操对接、调试排错到生产级优化,提供全链路标准化指导。
| 参数类型 | 参数名称 | 类型 | 是否必填 | 说明 | 应用示例 |
|---|---|---|---|---|---|
| 公共参数 | key | string | 是 | 调用密钥(开放平台获取) | 8a9b7c6d5e4f3g2h1i |
| secret | string | 是 | 调用秘钥(开放平台获取) | abcdef1234567890 | |
| api_name | string | 是 | 接口名称,固定为item_search | cgzb.item_search | |
| result_type | string | 否 | 响应格式,默认 JSON | json/xml | |
| cache | string | 否 | 是否启用缓存,默认 yes | yes/no | |
| 业务参数 | q | string | 是 | 搜索关键词,需 URL 编码 | 服务器采购 国产化 |
| region | string | 否 | 地区编码(多级用,分隔,从开放平台获取编码表) | 310000,310100(上海市 - 上海市) | |
| purchase_type | string | 否 | 采购类型 | public_bid(公开招标)/negotiation(竞争性谈判)/inquiry(询价) | |
| buyer_type | string | 否 | 采购人类型 | government(政府)/enterprise(企业)/institution(事业单位) | |
| budget_min | float | 否 | 最低预算(元) | 500000 | |
| budget_max | float | 否 | 最高预算(元) | 5000000 | |
| publish_time_min | string | 否 | 发布开始时间(格式:YYYY-MM-DD) | 2026-01-01 | |
| publish_time_max | string | 否 | 发布结束时间(格式:YYYY-MM-DD) | 2026-01-31 | |
| sort_type | string | 否 | 排序方式,默认publish_time_desc | publish_time_desc(发布时间降序)/budget_desc(预算降序) | |
| page_num | int | 否 | 页码,默认 1 | 1 | |
| page_size | int | 否 | 单页条数,默认 20,最大 50 | 50 |
注意事项
region必须使用开放平台提供的标准地区编码,禁止直接传入地区名称(如 “上海”),否则会导致筛选无效;- 签名生成需包含所有非空参数(含公共参数与业务参数),按参数名 ASCII 升序排序后拼接 secret 进行 MD5 加密;
- 多关键词组合建议用空格分隔(如 “服务器 国产化 采购”),接口支持自动分词模糊匹配。
| 字段分类 | 核心字段 | 说明 |
|---|---|---|
| 基础项目信息 | project_id | 采购 / 招标项目唯一 ID |
| project_name | 项目名称 | |
| project_code | 项目编号(政府采购备案号) | |
| region | 项目所属地区(省 / 市 / 区) | |
| purchase_type | 采购类型(公开招标 / 竞争性谈判等) | |
| buyer_type | 采购人类型 | |
| 预算与时间信息 | budget | 项目预算(元) |
| publish_time | 公告发布时间 | |
| bid_deadline | 投标截止时间 | |
| purchase_start_time | 采购开始时间 | |
| 采购人信息 | buyer_name | 采购人名称 |
| agent_name | 代理机构名称 | |
| 分页信息 | total | 搜索结果总数 |
| page_num | 当前页码 | |
| page_size | 单页条数 | |
| has_next | 是否有下一页(true/false) |
提示:
item_search仅返回项目基础信息,招标文件、投标要求、中标结果等详情需调用item_get接口获取。
| 权限类型 | 日调用上限 | 调用频率 | 适用场景 |
|---|---|---|---|
| 个人测试权限 | 100 次 / 天 | 2 次 / 秒 | 功能调试、个人研究 |
| 企业基础权限 | 1000 次 / 天 | 5 次 / 秒 | 中小型企业投标商机监控、市场调研 |
| 企业高级权限 | 10000 次 / 天 | 20 次 / 秒 | 大型集团采购管理、招标数据分析平台、政府采购审计 |
采购与招标item_search接口通常由政府采购网开放平台、省级公共资源交易平台或合规商业数据服务商提供,接入步骤如下:
key和secret(接口调用核心凭证),配置服务器 IP 白名单;cgzb.item_search接口权限,根据业务需求选择权限等级(基础 / 进阶 / 高级)。风险提示:严禁使用非合规爬虫、第三方代理接口抓取数据,违反《政府采购法》及平台协议会导致账号封禁、法律追责。
| 工具类型 | 推荐工具 | 用途 |
|---|---|---|
| 调试工具 | 开放平台调试工具 | 自动生成签名,验证参数与响应结果 |
| Postman | 模拟 GET/POST 请求,排查代码逻辑问题 | |
| 地区编码查询工具 | 获取标准地区编码,避免筛选错误 | |
| 开发依赖 | requests | 发送 HTTPS 请求 |
| hashlib | 生成 MD5 签名,确保接口安全 | |
| jsonpath-ng | 快速解析嵌套 JSON 响应数据 | |
| pandas | 批量整理项目列表数据,生成 Excel 报告 | |
| 辅助工具 | Redis | 缓存搜索结果,减少接口调用次数 |
| logging | 记录接口调用日志,便于审计与问题追溯 |
采购与招标接口采用key+secret 签名认证机制,签名生成步骤如下:
key1value1key2value2...的字符串格式;secret拼接在参数串末尾,生成签名原串;sign;sign添加到请求参数中,发送 HTTPS 请求。bash
pip install requests hashlib jsonpath-ng pandasimport requests import hashlib import time import logging import pandas as pd from urllib.parse import quote # 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex # 日志配置:记录调用日志,便于问题排查 logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", handlers=[logging.FileHandler("cgzb_item_search.log"), logging.StreamHandler()] ) # 配置信息(替换为你的开放平台信息) CONFIG = { "key": "你的接口key", "secret": "你的接口secret", "api_url": "https://api.cgzb-platform.com/cgzb/item_search", "result_type": "json", "cache": "yes" } def generate_sign(params: dict, secret: str) -> str: """生成采购招标接口签名(MD5加密)""" # 1. 按参数名ASCII升序排序 sorted_params = sorted(params.items(), key=lambda x: x[0]) # 2. 拼接参数为key1value1key2value2格式 param_str = "".join([f"{k}{v}" for k, v in sorted_params]) # 3. 拼接secret并MD5加密 sign_str = param_str + secret sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().lower() return sign def standardize_project_data(raw_project: dict) -> dict: """标准化采购招标项目数据,统一输出格式""" return { "项目ID": raw_project.get("project_id", ""), "项目名称": raw_project.get("project_name", ""), "项目编号": raw_project.get("project_code", ""), "所属地区": raw_project.get("region", ""), "采购类型": raw_project.get("purchase_type", ""), "采购人类型": raw_project.get("buyer_type", ""), "项目预算(元)": raw_project.get("budget", 0.0), "公告发布时间": raw_project.get("publish_time", ""), "投标截止时间": raw_project.get("bid_deadline", ""), "采购人名称": raw_project.get("buyer_name", ""), "代理机构名称": raw_project.get("agent_name", ""), "请求时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) } def cgzb_item_search( keyword: str, region: str = None, purchase_type: str = None, buyer_type: str = None, budget_min: float = None, budget_max: float = None, publish_time_min: str = None, publish_time_max: str = None, sort_type: str = "publish_time_desc", page_num: int = 1, page_size: int = 20 ) -> dict: """调用采购与招标item_search接口获取项目列表""" # 1. 校验必填参数 if not keyword: return {"success": False, "error_msg": "关键词不能为空", "data": [], "pagination": {}} # 2. 构建公共参数 params = { "key": CONFIG["key"], "api_name": "item_search", "result_type": CONFIG["result_type"], "cache": CONFIG["cache"], "q": quote(keyword, encoding="utf-8"), "sort_type": sort_type, "page_num": page_num, "page_size": min(page_size, 50) # 单页最大50条 } # 3. 补充分筛参数 if region: params["region"] = region if purchase_type: params["purchase_type"] = purchase_type if buyer_type: params["buyer_type"] = buyer_type if budget_min is not None: params["budget_min"] = budget_min if budget_max is not None: params["budget_max"] = budget_max if publish_time_min: params["publish_time_min"] = publish_time_min if publish_time_max: params["publish_time_max"] = publish_time_max # 4. 生成签名 sign = generate_sign(params, CONFIG["secret"]) params["sign"] = sign try: # 5. 发送HTTPS请求 response = requests.get( url=CONFIG["api_url"], params=params, timeout=10, verify=True # 生产环境建议开启证书验证 ) response.raise_for_status() # 抛出HTTP状态码异常 result = response.json() # 6. 解析响应结果 if result.get("error_response"): error = result["error_response"] error_msg = f"{error.get('code', '未知错误')}: {error.get('msg', '无错误信息')}" logging.error(f"搜索失败(关键词:{keyword}):{error_msg}") return {"success": False, "error_msg": error_msg, "data": [], "pagination": {}} search_result = result.get("item_search_response", {}).get("projects", {}) raw_projects = search_result.get("project", []) if not raw_projects: logging.warning(f"无匹配项目(关键词:{keyword})") return {"success": False, "error_msg": "无匹配采购/招标项目", "data": [], "pagination": {}} # 7. 标准化数据与分页信息 standard_projects = [standardize_project_data(proj) for proj in raw_projects] pagination = { "total": int(search_result.get("total", 0)), "page_num": page_num, "page_size": page_size, "has_next": search_result.get("has_next", False) } return {"success": True, "data": standard_projects, "pagination": pagination, "error_msg": ""} except requests.exceptions.RequestException as e: logging.error(f"网络请求异常(关键词:{keyword}):{str(e)}") return {"success": False, "error_msg": f"网络异常:{str(e)}", "data": [], "pagination": {}} except Exception as e: logging.error(f"数据解析异常(关键词:{keyword}):{str(e)}") return {"success": False, "error_msg": f"解析异常:{str(e)}", "data": [], "pagination": {}} # 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex # 调用示例 if __name__ == "__main__": # 搜索条件:服务器采购,上海市,公开招标,预算50万-500万,2026年1月发布 keyword = "服务器采购 国产化" region = "310000,310100" # 上海市-上海市地区编码 purchase_type = "public_bid" budget_min = 500000.0 budget_max = 5000000.0 publish_time_min = "2026-01-01" publish_time_max = "2026-01-31" # 调用接口 result = cgzb_item_search( keyword=keyword, region=region, purchase_type=purchase_type, budget_min=budget_min, budget_max=budget_max, publish_time_min=publish_time_min, publish_time_max=publish_time_max, page_size=20 ) if result["success"]: print(f"搜索成功:共找到 {result['pagination']['total']} 条项目") for proj in result["data"][:5]: # 打印前5条数据 print(f"项目ID:{proj['项目ID']} | 名称:{proj['项目名称']} | 预算:{proj['项目预算(元)']} | 截止时间:{proj['投标截止时间']}") # 保存为Excel df = pd.DataFrame(result["data"]) df.to_excel(f"采购招标项目列表_{keyword}.xlsx", index=False) # 翻页示例 if result["pagination"]["has_next"]: next_page_result = cgzb_item_search( keyword=keyword, region=region, purchase_type=purchase_type, budget_min=budget_min, budget_max=budget_max, publish_time_min=publish_time_min, publish_time_max=publish_time_max, page_num=2, page_size=20 ) print(f"下一页获取到 {len(next_page_result['data'])} 条数据") else: print(f"搜索失败:{result['error_msg']}")cgzb.item_search接口;| 问题现象 | 常见原因 | 解决方案 |
|---|---|---|
| 签名验证失败(401) | 1. key/secret 错误;2. 参数未按 ASCII 升序排序;3. 缓存参数(cache)未加入签名;4. 参数值含特殊字符未处理 | 1. 核对开放平台应用的 key/secret;2. 严格按参数名 ASCII 升序排序所有非空参数;3. 将 cache 参数加入签名生成;4. 对关键词等参数进行 URL 编码 |
| 权限不足(403) | 1. 未申请cgzb.item_search接口权限;2. 服务器 IP 不在白名单;3. 调用频率超限;4. 申请的权限等级不足 | 1. 在开放平台申请对应接口权限;2. 添加服务器 IP 到白名单;3. 降低调用频率,控制并发数≤权限上限;4. 升级权限等级,申请敏感数据访问权限 |
| 参数错误(400) | 1. 关键词为空;2. 地区编码格式错误(传入名称而非编码);3. page_size>50;4. 时间格式错误(非 YYYY-MM-DD) | 1. 确保 keyword 参数非空;2. 使用开放平台提供的标准地区编码;3. page_size 设置≤50;4. 时间参数格式统一为 YYYY-MM-DD |
| 无项目数据返回 | 1. 关键词无匹配;2. 筛选条件过严(如预算区间过小);3. 项目为涉密 / 撤回状态;4. 地区限制(仅本地企业可见) | 1. 简化关键词,去掉冗余限制条件;2. 放宽筛选条件(如扩大预算区间、延长时间范围);3. 在政府采购网搜索关键词,确认项目状态;4. 移除地区限制,或添加目标地区编码 |
| 响应超时(504) | 1. 网络波动;2. page_size 过大(如 50 条);3. 高峰期调用(工作日 9:00-11:00) | 1. 添加重试机制;2. 减小 page_size 至 20 条以内;3. 避开高峰期调用,或增加超时时间 |
has_next字段判断是否继续翻页,避免无效请求;多关键词 / 多地区查询时采用异步并发(aiohttp),并发数≤权限允许的频率上限(如企业基础权限 5 次 / 秒);cgzb_search_关键词_地区_采购类型_页码,新发布项目缓存 5 分钟,历史项目缓存 30 分钟,减少重复调用;project_id去重,避免同一项目重复出现在不同页码或不同关键词搜索结果中;item_search获取项目 ID 列表,批量调用item_get接口获取招标文件、投标要求等详情,实现 “搜索 - 详情” 全链路数据采集;item_search接口,筛选符合企业资质的项目,当新项目发布时,通过邮件 / 短信自动推送投标提醒;