如何使用招标网API获取项目详情?

用招标网 API 获取项目详情,核心是先通过列表接口拿到项目唯一 ID,再用详情接口传入 ID 获取完整信息 。下面给你一套可直接落地的完整流程 + 代码示例 + 避坑要点(以主流招标网 / 标讯 API 为例,通用逻辑一致)。


一、整体流程(3 步搞定)

  1. 获取项目列表 :按关键词 / 地区 / 时间筛选,拿到每条公告的项目 ID / 公告 ID(唯一标识)。
  2. 调用详情接口:用上一步拿到的 ID,请求详情接口,获取完整结构化数据(标题、预算、采购人、中标人、附件、正文等)。
  3. 数据处理与存储:解析 JSON,去重、清洗、入库 / 导出。

二、关键前提

  • 已在对应平台(招标网、APISpace、阿里云市场等)开通 API 权限 ,拿到:
    • API Key / Token
    • 接口地址(列表接口 + 详情接口)
    • 字段说明文档
  • 明确你要的字段:项目编号、标题、发布时间、预算金额、采购人、代理机构、中标人、中标金额、公告类型、附件链接、正文内容等。

三、通用接口参数说明(以 APISpace 标讯 API 为例)

1)列表查询接口(获取 ID)

  • 请求方式:GET/POST
  • 核心参数
    • keyword:关键词(如 "存储芯片""服务器""EPC")
    • province:省份(如 "北京""广东")
    • publishStartTime/publishEndTime:发布时间范围
    • noticeType:公告类型(招标 / 中标 / 变更 / 废标等)
    • pageNum/pageSize:分页
  • 返回核心字段
    • id/noticeId/projectId详情接口必须的唯一 ID
    • title:标题
    • publishTime:发布时间
    • area:地区

2)详情查询接口(获取完整信息)

  • 请求方式:GET/POST
  • 核心参数
    • id/noticeId:从列表接口拿到的唯一 ID(必填)
  • 返回核心字段 (结构化):
    • 基础信息:项目编号、标题、公告类型、发布时间、截止时间
    • 采购信息:采购人、代理机构、联系人、联系电话(部分脱敏)
    • 预算与中标:预算金额、中标人、中标金额、中标日期
    • 内容:公告正文(HTML / 纯文本)、附件下载链接
    • 其他:行业分类、项目地址、监督部门等

四、Python 完整示例(可直接改参数跑)

APISpace 全国招投标查询 API 为例(其他平台逻辑一致,仅 URL、Header、参数名略有差异)。

步骤 1:安装依赖

bash

运行

复制代码
pip install requests

步骤 2:完整代码(列表→详情→解析)

python

运行

复制代码
import requests
import json

# ========== 1. 配置信息(替换成你自己的) ==========
API_KEY = "你的APISpace Token"
LIST_API_URL = "https://eolink.o.apispace.com/1063/bids/search"  # 列表接口
DETAIL_API_URL = "https://eolink.o.apispace.com/1063/bids/detail" # 详情接口

HEADERS = {
    "X-APISpace-Token": API_KEY,
    "Content-Type": "application/json"
}

# ========== 2. 第一步:查询列表,获取项目ID ==========
def get_bid_list(keyword, province, start_time, end_time, page_size=10):
    params = {
        "keyword": keyword,
        "province": province,
        "publishStartTime": start_time,
        "publishEndTime": end_time,
        "pageSize": page_size,
        "pageNum": 1
    }
    try:
        resp = requests.get(LIST_API_URL, headers=HEADERS, params=params, timeout=15)
        resp.raise_for_status()
        data = resp.json()
        # 打印列表结构,方便你看字段名
        # print(json.dumps(data, ensure_ascii=False, indent=2))
        return data.get("data", {}).get("list", [])
    except Exception as e:
        print(f"列表接口调用失败: {e}")
        return []

# ========== 3. 第二步:根据ID获取详情 ==========
def get_bid_detail(notice_id):
    params = {
        "id": notice_id  # 注意:不同平台参数名可能是 noticeId/projectId
    }
    try:
        resp = requests.get(DETAIL_API_URL, headers=HEADERS, params=params, timeout=15)
        resp.raise_for_status()
        data = resp.json()
        return data.get("data", {})
    except Exception as e:
        print(f"详情接口调用失败: {e}")
        return None

# ========== 4. 主流程 ==========
if __name__ == "__main__":
    # 1)查询条件(按你的业务改)
    KEYWORD = "存储芯片"
    PROVINCE = "全国"
    START_TIME = "2026-01-01"
    END_TIME = "2026-01-22"

    # 2)获取列表
    bid_list = get_bid_list(KEYWORD, PROVINCE, START_TIME, END_TIME, page_size=5)
    if not bid_list:
        print("未查询到招标信息")
        exit()

    # 3)遍历列表,逐个获取详情(示例取前2条)
    for idx, bid in enumerate(bid_list[:2], 1):
        notice_id = bid.get("id")  # 关键:拿到ID
        title = bid.get("title", "")
        publish_time = bid.get("publishTime", "")

        print(f"\n===== 第{idx}条:{title} =====")
        print(f"发布时间: {publish_time}")
        print(f"公告ID: {notice_id}")

        # 4)获取详情
        detail = get_bid_detail(notice_id)
        if not detail:
            continue

        # 5)解析你需要的字段(按需提取)
        project_code = detail.get("projectCode", "")  # 项目编号
        purchaser = detail.get("purchaser", "")       # 采购人
        agency = detail.get("agency", "")             # 代理机构
        budget = detail.get("budget", "")             # 预算金额
        winner = detail.get("winner", "")             # 中标人
        win_amount = detail.get("winAmount", "")      # 中标金额
        content = detail.get("content", "")[:300] + "..."  # 正文预览

        print(f"项目编号: {project_code}")
        print(f"采购人: {purchaser}")
        print(f"代理机构: {agency}")
        print(f"预算金额: {budget}")
        print(f"中标人: {winner}")
        print(f"中标金额: {win_amount}")
        print(f"正文预览: {content}")

五、不同平台的 "ID 字段名" 差异(常见坑)

很多人调用详情失败,就是ID 字段名不对,按你用的平台对应改:

平台 列表返回 ID 字段 详情接口参数名
APISpace id id
招标网(hq.zhaobiao.cn noticeId/projectId noticeId/projectId
中国采招网 id id
阿里云市场标讯 API notice_id notice_id

解决方法:先打印列表返回的完整 JSON,找到唯一标识字段,再填到详情接口。


六、必做优化与避坑(生产环境必备)

1)去重(避免重复调用详情)

  • noticeId/projectId 做唯一键,存入数据库 / Redis / 本地文件,已获取过的不再请求。

  • 示例(简单本地去重): python

    运行

    复制代码
    import os
    HISTORY_FILE = "bid_history.txt"
    
    def is_fetched(notice_id):
        if not os.path.exists(HISTORY_FILE):
            return False
        with open(HISTORY_FILE, "r", encoding="utf-8") as f:
            return notice_id in f.read().splitlines()
    
    def mark_fetched(notice_id):
        with open(HISTORY_FILE, "a", encoding="utf-8") as f:
            f.write(notice_id + "\n")

    调用时:

    python

    运行

    复制代码
    if is_fetched(notice_id):
        continue
    detail = get_bid_detail(notice_id)
    mark_fetched(notice_id)

2)分页与并发控制

  • 列表接口默认只返回一页,需循环 pageNum 拉全量。
  • 不要并发过高(QPS 5-10 以内),避免被限流 / 封号。
  • 延时time.sleep(0.5)time.sleep(1)

3)异常处理

  • 超时重试:tenacity 或简单 for i in range(3) 重试。
  • 401/403:检查 API Key 是否过期、权限是否开通。
  • 429:限流,降低调用频率或升级套餐。

4)数据清洗

  • 金额:统一单位(元 / 万元),去除 "¥""万元" 等字符,转数字。
  • 时间:统一格式 YYYY-MM-DD HH:MM:SS
  • 正文:HTML 转纯文本(用 BeautifulSoup)。

七、进阶:实时推送(替代轮询)

如果需要秒级 / 分钟级 获取新公告,优先用平台的WebHook / 消息推送

  1. 在平台配置推送地址(你的服务接口)。
  2. 设置订阅条件(关键词、地区、行业)。
  3. 平台有新公告时,主动 POST 给你,包含 noticeId,你再调用详情接口。
  • 优点:实时、省调用量、成本低。
  • 缺点:需要部署公网可访问的接收服务。
相关推荐
南山乐只1 小时前
Qwen Code + OpenSpec 实战指南:AI 驱动开发的从安装到落地
java·人工智能·后端
qq_406176141 小时前
深入剖析JS中的XSS与CSRF漏洞:原理、攻击与防御全指南
服务器·开发语言·前端·javascript
RFCEO1 小时前
HTML编程 课程六、:HTML5 新增多媒体标签
前端·html·html5·多媒体标签·嵌入音频、视频、动画
2501_945837431 小时前
DPU全栈卸载,NVIDIA BlueField-3释放云服务器核心算力
服务器
Suchadar1 小时前
在Linux中安装Python
linux·运维·服务器
AI科技星1 小时前
从质能关系到时空几何:光速飞行理论的框架对比与逻辑验证
服务器·人工智能·线性代数·算法·矩阵
yanyu-yaya1 小时前
速学兼复习之vue3章节4
前端·vue.js·前端框架
Mr-Wanter2 小时前
vue 数据反显时数字/字母不换行导致的样式问题
前端·javascript·vue.js
代码写到35岁2 小时前
【Java 单体架构改造 微服务 网关遇坑之 跨域配置】
java·微服务·架构