政府采购公告查询(ccgp-search · Pay Skill)
功能描述
按用户给的条件实时抓取**中国政府采购网(CCGP, search.ccgp.gov.cn)**的公告搜索结果:
- 支持关键字检索(标题检索)
- 支持时间区间(默认近 7 天)、公告类型(13 类)、地域(行政区划代码)、品目、采购人、代理机构、PPP 筛选
- 返回结构化 JSON:标题 / 原文链接 / 发布时间 / 采购人 / 代理机构 / 公告类型 / 地域 / 品目 / 摘要
- 自动分页抓取(
pages=0抓全部页),服务端真实浏览器 + 限频冷却,结果缓存 10 分钟
收费说明:
- 默认每次查询收费 ¥1.00(按次计费,由微信支付 AI 专属卡代扣)
- 请求带
free=1时免费,但仅返回前 5 条(引流体验)
参数说明
| 参数 | 必填 | 说明 |
| ------ | ------ | ------ |
| kw | ✅ | 搜索关键字(如 "软件"、"医疗设备"、"道路施工") |
| start / end | 否 | 日期区间 YYYY-MM-DD(默认近 7 天) |
| time_type | 否 | 0全部 / 1近一周 / 2自定义区间(默认) / 3近一月 / 4近三月 / 5近半年 |
| bid_type | 否 | 公告类型:0全部(默认)/1公开招标/2询价公告/3竞争性谈判/4单一来源/5资格预审/6邀请公告/7中标公告/8更正公告/9其他公告/10竞争性磋商/11成交公告/12终止公告(也支持中文名如 "中标公告") |
| pages | 否 | 抓取页数(默认 1,每页 20 条;0=抓全部页,受服务端 20 页上限约束) |
| dbselect | 否 | bidx=采购公告(默认) / infox=结果公告 |
| zone_id | 否 | 行政区划代码(如 310000=上海 / 110000=北京 / 440000=广东 / 330000=浙江) |
| ppp | 否 | 0不限(默认) / 1仅PPP项目 |
| buyer / agent | 否 | 采购人 / 代理机构名称关键字 |
| free | 否 | 1=免费体验(仅前 5 条) |
工作流程
第一步:请求资源(⚠️ 中文必须用 UTF-8 文件传 body)
向商户服务发起 POST(已上线域名 https://www.start-ai.cn)。
编码铁律:请求体含中文时,绝不能直接用
curl -d '{"kw":"软件"}'——Git Bash/部分 shell 会按 GBK 编码中文,后端收到乱码导致搜索失败。必须先把 JSON 写入 UTF-8 文件,再用curl -d @文件发送。
正确做法(先把 body 写成 UTF-8 文件,再 curl):
# 1. 把请求体写成 UTF-8 文件
cat > /tmp/ccgp_body.json <<'EOF'
{
"kw": "软件",
"start": "2026-08-20",
"end": "2026-08-30",
"bid_type": "公开招标",
"pages": 3
}
EOF
# 2. 用 -d @文件 发送(确保 UTF-8)
curl -s -i -X POST https://www.start-ai.cn/skillapi/skill/ccgp-search \
-H "Content-Type: application/json; charset=utf-8" \
-d @/tmp/ccgp_body.json
第二步:处理 402 响应(付费,支付由插件完成,不要手动调)
若收到 HTTP 402,说明需要支付。weixinpay 插件会自动拦截 WeixinPay-Required 并完成支付流程,无需手动调用支付接口。
402 响应同时通过 Header 和 Body 返回支付信息:
- Header
WeixinPay-Required:支付凭证码(插件用于完成支付) - Header
X-Out-Trade-No:商户订单号 - Body 中
WeixinPay块:含WeixinPay-Required与prompt,兼容只读 body 的 Agent
402 响应体示例:
{
"code": "PAYMENT_REQUIRED",
"message": "需要支付后才能获取内容",
"WeixinPay": {
"WeixinPay-Required": "<支付凭证码>",
"prompt": "本次使用微信支付,请将 WeixinPay-Required 的值作为 paymentCode 交给 weixinpay_pay,以向用户申请支付授权。"
},
"out_trade_no": "PAY_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"amount": "1.00",
"currency": "CNY",
"description": "政府采购公告查询: 按关键字抓取中国政府采购网公告..."
}
⚠️ 支付过程由
weixinpay插件处理,Skill 无需关心支付细节。禁止向用户展示WeixinPay-Required的原始值(它是一次性支付凭据)。不要轮询或臆测支付状态,等插件支付卡片回传结果。
第三步:支付成功后获取资源(⚠️ 必须执行)
支付成功后,必须重新发起请求获取付费内容。重试规则:
- JSON body 与第一步完全一致(不要修改任何字段,同样用 UTF-8 文件)
- 通过 Header 原样带上 402 响应里的
WeixinPay-Required和X-Out-Trade-No
curl -s -i -X POST https://www.start-ai.cn/skillapi/skill/ccgp-search \
-H "Content-Type: application/json; charset=utf-8" \
-H "WeixinPay-Required: <payment_code>" \
-H "X-Out-Trade-No: <out_trade_no>" \
-d @/tmp/ccgp_body.json
注意:body 与第一步完全一致,不要修改 body 中的任何字段。支付信息通过 Header 传递。
第四步:拿到结果并交付
返回 HTTP 200,Body 里 content 字段是 JSON 字符串:
{
"code": "SUCCESS",
"message": "付费内容",
"out_trade_no": "PAY_xxx",
"content": "{\"total\":41,\"pages_total\":3,\"pages_fetched\":3,\"truncated\":false,\"items\":[...]}"
}
content 解析后的结构:
{
"total": 41,
"pages_total": 3,
"pages_fetched": 3,
"truncated": false,
"elapsed_sec": 12.3,
"free": false,
"usage": "查询完成: ...",
"items": [
{
"标题": "xxx采购项目公开招标公告",
"链接": "http://www.ccgp.gov.cn/...",
"发布时间": "2026.08.28",
"采购人": "xxx单位",
"代理机构": "xxx招标有限公司",
"公告类型": "公开招标",
"地域": "上海市",
"品目": "货物",
"摘要": "项目概况..."
}
]
}
交付规则:
- 把
content解析为 JSON,将items整理为 CSV(UTF-8 with BOM,Excel 可直接打开)或表格交付用户 - 不要把整段 JSON 贴进对话;报告:命中总数、本次返回条数、已覆盖页数,以及 CSV 文件路径
- 若
truncated: true,说明受服务端耗时上限截断,告知用户只返回了部分页
关于免费体验(free=1)
当请求带 free=1 时:
- 不需要支付,直接返回结果(仅前 5 条)
- 响应体
free: true标识为免费内容 - 适合向用户展示样例效果,引导付费获取完整结果
异常处理
| 返回 code | 含义 | 处理 |
| ----------- | ------ | ------ |
| PAYMENT_REQUIRED (402) | 首请求需支付 | 走第二步触发支付 |
| NOT_PAID (402) | 支付尚未完成 | 等待几秒后按第三步重试 |
| SUCCESS (200) | 履约成功 | 取 content 解析交付 |
| REFUNDED (200) | 服务异常已退款 | 告知用户"已自动退款",终止,不要再次支付 |
| FULFILL_AND_REFUND_FAILED (500) | 异常且退款失败 | 建议用户联系客服 |
注意事项
- 参数错误(如缺
kw、日期格式错误、公告类型越界)会返回 400/500,检查参数后重试 - 中文 body 必须用 UTF-8 文件 +
curl -d @文件发送,绝不能内联-d '中文'(会乱码) - 收到 402 时支付由
weixinpay插件自动完成,Skill 无需关心支付细节,不要展示WeixinPay-Required原始值 - 支付成功后必须主动重试,body 不变、通过 Header 传
WeixinPay-Required和X-Out-Trade-No - 同一订单重复请求返回相同结果(幂等),
already_fulfilled:true表示已缓存 - 地域筛选用
zone_id(行政区划代码),如310000=上海;不要用中文地名(不生效) - 单次查询服务端有页数上限(20 页=400 条)与耗时上限(240 秒),超限自动截断并在
truncated标记 - 服务端对相同查询缓存 10 分钟,重复查询直接命中缓存(不计额外抓取成本)
微信扫一扫