国网招标数据
Overview
把国家电网电子商务平台(ECP)的招标公告、采购公告、中标候选人公示、成交结果公告自动采集下来,沿"招标公告 → 中标(成交)结果 → 中标价"一路解析入账,建成并维护一张"中标人汇总"总台账,之后转为只盯新公告的增量巡检(不再翻历史)。信息包含批次、采购编号、分标编号/包号、项目名称、项目地点、招标人/采购人、招标代理机构、中标人(成交供应商)、中标价(来自候选人公示)、报名截止与公告发布日期。默认盯陕西,想看哪个省就换成哪个省——说一句"改成江苏"即可自动带出其各地市一并搜(省名会漏掉标题不含省名的地市公司);业务线默认工程服务,说一句"抓物资"就切到物资类采购,也可指定具体物资名(变压器 / 电缆 / 绝缘子)。台账按业务线分列(工程服务 16 列 / 物资 21 列),自动按"项目时间 → 分标 → 分包"三级排序,说明行始终留在表尾。数据来自国网 ECP 公开页面,省份与业务线都只是搜索关键词——换省换线不用改代码;随包只含文本配置与脚本,示例台账在首次使用时由脚本生成,不附带任何二进制。使用前提:需自备一个已登录并配置国网 ECP 数字证书的 Edge 用户目录(环境变量 SGCC_EDGE_PROFILE 指定)。
本技能为通用版:列表页是全国统一入口,省份与业务线(工程服务 / 物资 / 具体物资名)
都只是搜索关键词——换省只需换省名+该省地市,换业务线只需换搜索词(如 物资 / 变压器)。
台账按业务线选不同列模板(templates/ledger_columns.json),目前内置「工程服务」「物资」两套。
需要真实中标数据请联系作者:348760700@qq.com(随包不含任何真实数据)。
产物总台账:由 scripts/ledger_scan.py 按业务线模板维护(工程服务 16 列 / 物资 21 列,对应不同 sheet)。台账 xlsx 由 scripts/make_ledger.py 按需生成,不随包附二进制:python scripts/make_ledger.py --template 工程服务 生成含脱敏示例行的台账,加 --blank 生成空台账供填真实数据;示例内容(标题/表头/示例行/说明含邮箱)存于 templates/ledger_samples.json(纯文本)。需要真实数据请联系作者:348760700@qq.com。台账路径可通过环境变量 SGCC_LEDGER 覆盖(指向你自己的最新台账);ledger_scan / sort_ledger 在默认台账缺失时会自动生成。
铁律(违反即返工)
- 准确性第一——不臆测、不外推;对不上的留空写清,别编。
- 只在用户指定的工作区内新建/修改/删除文件;其它目录只读参考、不写入(避免污染其它项目工作区)。
- Downloads 里下载的文件不删、不动、不改名;要处理先复制到本工作区再解压。
- 只抓 2026 年、只抓"市场化项目服务授权采购(原集体企业/子公司)"这条线(含其物资类采购);省份与业务线按你给的关键词过滤(省份=省名,业务线=物资/具体物资名/工程/服务等)。南瑞/科东/±800kV 直流、营业厅电子屏等明显无关项目不碰。
- 少开并行任务(曾因并行过多系统崩溃);一个标抓完处理完再下一个。
- 浏览器脚本收尾必须杀 Edge 进程树(见"环境"),否则 headless 残留一直下载。
- 表格里已有真实数字不覆盖;占位"待补/待结果公告"可覆盖。
- 少用截图/读图(积分消耗大),优先纯程序化文本输出。
环境(每次开工先确认)
- Python 环境:脚本依赖
openpyxl与websocket-client。优先使用本机托管 Python venv(已内置这两包);若用系统python/python3,请先pip install openpyxl websocket-client。
脚本里的python指运行环境里的 Python 解释器。 - 抓 ECP 用 headless Edge + CDP:
msedge.exe --headless=new --remote-debugging-port=9333 --user-data-dir=<你的Edge用户数据目录> --no-first-run
必须用一个已登录、并已配置好国网 ECP 数字证书的 Edge 用户数据目录,通过环境变量SGCC_EDGE_PROFILE指定(脚本无内置默认值,未设置会报错提示)。换目录或证书未配置会导致无法访问需登录的列表页。
Edge 可执行文件路径通过SGCC_EDGE_BIN指定,缺省为C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe。 - 收尾必做:
python scripts/kill_edge.py(查占用 9333 的 msedge →taskkill /PID <pid> /T /F)。
平台入口(四类列表页)
前缀 https://ecp.sgcc.com.cn/ecp2.0/portal/#/list/list-etp/,后缀:
| 类型 | 后缀 |
|---|---|
| 招标公告 | 202111091047301_14_2020110706504025 |
| 采购公告 | 202111091047301_14_2020110706504027 |
| 中标候选人公示 | 202111091047301_14_2020111115278748 |
| 中标(成交)结果公告 | 202111091047301_14_2020111115278758 |
- 结果公告只有中标人、没有价;中标价只在"候选人公示"里,公示期一过就撤,须及时抓。
- 详情页不用登录;但列表页行内没有 href/urlkey,必须真实鼠标点整行 tr 才会新开
doci-bid/doci-win标签拿到 urlkey。
工作流
Step 1 · 建立基线(不要凭记忆假设现状)
python scripts/ledger_scan.py [台账路径] [--template 工程服务|物资]
输出数据行数、批次分布、中标价/中标人空值数、最新公告日期(列按所选模板)。据此判断"新"的起点。
> 台账 xlsx 用 python scripts/make_ledger.py --template 工程服务 生成(含脱敏示例行;--blank 出空台账供填真实数据);用自有台账则传路径或设 SGCC_LEDGER。台账缺失时本步会自动生成。
Step 2 · 增量发现新公告
python scripts/sgcc_scan_all.py # 全国最新(判断平台更新到哪天)
python scripts/sgcc_scan_all.py --line 物资 # 全国物资类最新
python scripts/sgcc_search_kw.py --province 江苏 # 江苏线(自动补搜江苏各地市)
python scripts/sgcc_search_kw.py --province 江苏 --line 物资 # 江苏物资类
python scripts/sgcc_search_kw.py 江苏 # 等价写法(单关键词, 向后兼容)
⚠️ 列表页是全国统一入口,省份 = 省名、业务线(物资/具体物资名) = 搜索词。脚本按 --province 自动从 templates/provinces.json 取该省省名+地市补搜(省名会漏掉标题不含省名的地市公司)。换省把示例省名换成目标省名即可;换业务线加 --line 物资 或具体物资名(变压器/电缆/绝缘子)。
搜到的条目要再按"是否目标批次/业务线"人工过滤,别把明显无关项目(如营业厅电子屏)误纳入。
Step 3 · 取详情 + 下载附件
- 在列表页用
Input.dispatchMouseEvent真实鼠标点整行 tr(JSclick()/dispatchEvent无效),新开标签拿 urlkey。只认点击后"新增"的标签页。 - 下载附件严格按"终极姿势"(见
references/踩坑与排障.md§2):
Browser.setDownloadBehavior发在 browser 级 websocket →scrollIntoView()把按钮滚进视口 →
校验getBoundingClientRect()在屏内 → 真实鼠标点击 → 监听Browser.downloadWillBegin。 - 落盘是 UUID 临时名(无扩展名),复制到本工作区改名
.zip;用 mtime 变化检测,不靠文件名(同名会自动加序号)。
Step 4 · 解析入账 / 回填(先选业务线模板)
按 references/数据口径与台账结构.md 执行:先用 --template 选定业务线(工程服务 / 物资)→
附件解压 → 验证标题含预期批次关键词 → 按该模板列结构解析表格 →
回填分包名称/项目地点/中标价(物资为中标总价/单价/制造商)→ 写回对应台账。
Step 5 · 排序(回填后立即做,保持台账有序)
回填/增量写库后运行排序脚本,让台账维持固定顺序(便于比对与增量巡检):
python scripts/sort_ledger.py [台账路径] [--template 工程服务|物资]
固定排序规则(勿改,按模板键列):① 项目时间=批次名"第X次"序号(第一次→…→第十六次);② 分标号=标XX 取数值升序;③ 分包号=包XX 取数值升序。说明行保持表尾,原地重写并保留单元格样式。
Step 6 · 回读验证(必做)
openpyxl 回读首/中/末行 + 全表扫批次分布,确认:没错位、没重复、说明行仍在表尾、批次按时间、组内按分标/包有序。
台账结构(按业务线模板,列数不同)
台账按业务线选不同列模板,定义见 templates/ledger_columns.json。每套模板含:sheet 名、列名列表、排序键列(批次/分标/包)、中标人/中标价列、默认台账路径(default_file,由 make_ledger 生成)。当前内置两套:
- 工程服务(sheet
中标人汇总,16 列):A 批次|B 采购编号|C 结果序号|D 项目名称|E 分标编号|F 包号|G 分标名称|H 分包名称|I 项目地点|J 中标人(成交供应商)|K 代理服务费(元)|L 招标人/采购人|M 招标代理机构|N 中标价(元,来自候选人公示)|O 报名截止|P 公告发布日期 - 物资(sheet
中标人汇总_物资,21 列):在工程服务基础上,把 G/H 替换为 物资类别/物资名称,并增加 主要物资名称、物料编码/规格型号、制造商、单价(元)、数量 等物资字段(详见templates/ledger_columns.json)。
通用约定:第 1 行标题、第 2 行表头、数据从第 3 行起、最后一行是"说明行"(勿当数据);排序键(批次"第X次"→分标标XX→包XX)两套模板一致。
详细口径(中标价单位、入围制、地点三级提取、开标记录价、物资字段等)见 references/数据口径与台账结构.md。
增量巡检要点(台账建成后的常态)
- 采购/招标公告 → 新项目立即入库(不等结果),填 D/E/F、G/H/I(取自附件"项目需求一览表")、L、M、O、P。
- 候选人公示 → 抓 N 列中标价(公示期只有几天,过期看不到,这是补价唯一通道)。
- 结果公告 → 补 J 列中标人/成交供应商。
- 本地优先:下附件前先翻本工作区已有资料和 Downloads 已下 zip,有就直接用,不重复下载。
- 包号对不上时,以结果公示/候选人公示原文为准。
已知结构性事实:部分省份(以陕西为例)原集体企业/子公司这条线 2026 年没有候选人公示(最新仅 2025-11-19),
因此 N 列空值无法从公示补,属正常,不是遗漏。
资源
scripts/
make_ledger.py [--template 工程服务|物资] [--blank] [--out FILE] [--force]— 生成台账 xlsx(不随包附二进制,用前按需生成;--blank出空台账供填真实数据,默认含脱敏示例行)ledger_scan.py [台账路径] [--template 工程服务|物资]— 按模板基线扫描(批次分布/中标价·中标人空值/最新日期;台账缺失自动生成)sort_ledger.py [台账路径] [--template 工程服务|物资] [--dry-run]— 按"项目时间→分标→分包"三级排序,说明行留表尾sgcc_scan_all.py [--line 物资] [--out FILE]— 四类列表页无关键词扫描,看平台最新到哪天(可按业务线过滤)sgcc_search_kw.py [关键词] [--province 江苏] [--line 物资] [--out FILE]— 按省份(+地市)+业务线搜索四类列表页,抓标题+日期kill_edge.py— 清理占用 9333 端口的 Edge 进程树(收尾必跑)
templates/ 与 配置
templates/ledger_columns.json— 业务线列模板(工程服务/物资),定义 sheet、列、排序键、中标人/中标价列、默认台账路径templates/ledger_samples.json— 脱敏示例内容(标题/表头/示例行/含邮箱说明行),纯文本,供make_ledger.py生成 xlsxtemplates/provinces.json— 省份→地市清单(用于--province自动补搜地市),可增删
references/
数据口径与台账结构.md— 列定义、中标价单位规则、入围制、地点三级提取、开标记录价、物资字段、批次命名踩坑与排障.md— 说明行禁批量插行、GBK 解压、附件下载终极姿势、合并单元格、headless 残留、关键词漏地市
作者与联系
- 作者:安朋康|348760700@qq.com