技术专题 01 / 2026-10-16 / 参考实现

招标信息监测:从公告采集到目标命中与邮件摘要

以地区、关键词和预算为条件,构建可解释的招标筛选流程,并处理重复、延期与撤回。

本篇展示可运行的离线规则原型。来源采集、客户订阅后台及定时邮件投递属于后续工程范围。示例数据不用于实际投标、政策申报或业务判断。

技术档案

档案编号YM-TECH-20261016-01 / v1.0
作者与发布主体合肥域明科技有限责任公司
实现状态设计文章 + 浏览器离线演示 + Python参考实现;不代表新增生产服务上线。
运行环境Python 3.10及以上,标准库;浏览器演示无构建依赖。
测试与范围10项Python单元测试;演示页面使用5条固定样本。没有验证真实来源覆盖率或邮件送达率。

架构与流程

招标商机监测四阶段架构图
图1:登记公告来源 → 保留原文与版本 → 规则判断与复核 → 生成客户摘要。每一步保留来源和处理依据。

实现逻辑

问题定义:客户需要的不是更多链接

同一项目可能出现在多个站点,也可能先发布采购意向,再发布招标公告和更正公告。仅按关键词发送所有链接,会把重复、过期和不适用的信息交给客户。本方案把目标拆成三个可核查条件:业务是否相关、硬性条件是否满足、是否存在足够证据。输出不是一个神秘的相关度分数,而是命中原因、排除原因和待核验字段。

来源层:先定义覆盖范围,再谈及时性

生产系统应为每个来源配置公开接口、订阅源或允许访问的网页适配器,记录来源名称、栏目、检查间隔、最近成功时间和解析版本。列表发现新公告后,再抓取详情与必要附件。保存发布日期、抓取时间、原始地址和正文指纹;附件无法解析时进入人工复核队列,不能把空内容当成无相关信息。HTTP条件请求可以减少未变化内容的重复传输;采集失败应退避并记录,不等于来源当天没有更新。演示版不连接任何真实采购平台。

匹配层:硬过滤优先,缺失值单独处理

演示规则支持任一关键词或全部关键词、排除词、地区和最低预算。预算统一使用万元。正文命中关键词但地区不符,仍被排除;原文未写预算且客户设置预算门槛时,进入待复核,而不是填成零或猜测金额。已撤回和超过截止日期的项目不进入新商机列表。截止日按日期比较仅为演示简化,生产应保存带时区的精确截止时刻并考虑报名与投标两个不同窗口。

版本层:去重不应吞掉更正通知

用来源标识和公告编号定位记录,用内容指纹判断版本变化。跨站转载需要另设项目实体关联,不能仅靠相同标题自动合并。更正公告如果有独立公告编号,应通过关联项目编号指向原公告。示例代码演示同一编号多版本取最新的情况;生产中必须保留历史快照。如果已通知客户的项目被延期或撤回,应发送更新事件,即使它不再满足当前筛选条件。

交付层:邮件不是数据库的最终状态

将待发送邮件先写入发件队列表,以客户、公告版本、规则版本组成幂等键,防止同一版本反复入队。SMTP成功只代表邮件服务器接受,不代表客户已经阅读。生产需要记录发送尝试、退信和退订,遇到网络超时后的送达状态不明,应通过邮件服务商事件核对。页面只生成邮件预览,Python示例只输出EML文件;没有自动采集、没有实际邮件发送。

参考数据结构

下表是本专题的标准化字段,不是新发布的线上API响应契约。

字段含义处理要求
source + id来源与公告唯一标识定位记录,跨站项目另建关联
updated_at / version更新时间与内容指纹识别更新,保留旧版本
budget / deadline万元 / 截止日期缺失保留为空,不补猜
source_url / text原文地址与证据片段每条摘要可回查依据
查看完整样本记录
{
  "id": "tender-1",
  "kind": "tender",
  "source": "fixture",
  "title": "示例学校心理设备采购",
  "text": "采购心理测评设备与配套服务,预算50万元。",
  "region": "安徽",
  "budget": 50,
  "status": "published",
  "deadline": "2026-10-30",
  "updated_at": "2026-10-16T08:00:00+08:00",
  "published_at": "2026-10-16T07:30:00+08:00",
  "fetched_at": "2026-10-16T08:05:00+08:00",
  "application_open": null,
  "platform": "示例公开栏目",
  "source_url": "https://example.invalid/tender/1"
}

核心代码

离线参考代码:三态目标匹配。完整文件和测试见资料包。

def match(record, rule, as_of):
    text = (record['title'] + ' ' + record['text']).casefold()
    reasons = []
    failures = []
    pending = []
    terms = [word for word in rule['keywords'] if word.casefold() in text]
    if not rule['keywords']:
        raise ValueError('At least one keyword is required')
    required = len(rule['keywords']) if rule['mode'] == 'all' else 1
    if len(terms) < required:
        failures.append('keyword')
    else:
        reasons.append('keywords: ' + ', '.join(terms))
    if any(word.casefold() in text for word in rule['exclude']):
        failures.append('excluded')
    if rule['region'] != 'all' and record['region'] != rule['region']:
        failures.append('region')
    if record['status'] in ('withdrawn', 'repealed'):
        failures.append('inactive')
    if record.get('deadline') and date.fromisoformat(record['deadline']) < as_of:
        failures.append('expired')
    minimum = rule.get('minimum_budget', 0)
    if minimum > 0:
        if record.get('budget') is None:
            pending.append('budget_unknown')
        elif record['budget'] < minimum:
            failures.append('budget')
    if record['kind'] == 'policy' and record.get('application_open') is not True:
        pending.append('application_not_confirmed')
    state = 'excluded' if failures else 'review' if pending else 'matched'
    return {'id': record['id'], 'state': state, 'reasons': reasons,
            'failures': failures, 'pending': pending}

复现方式

python -m unittest -v
python monitor.py tender-monitoring.json --output output/tender-monitoring

在资料包的 examples 目录运行,生成 analysis.json 与 digest.eml。没有真实采集或邮件发送。

页面展示

招标商机监测交互演示页面:规则配置、命中状态与证据
图2:本专题实际可操作的离线演示页面,不是生产环境截图。
调整目标并查看结果

验收口径与实现边界

  • 任一关键词和全部关键词产生不同结果
  • 排除词、地区和截止日期优先于关键词命中
  • 预算未知进入待复核,而非默认符合
  • 同一来源同一编号取最新版本
  • 重复发送键相同,客户或版本改变时发送键不同

生产化还需要来源适配器、权限与租户隔离、审核记录、调度、持久化和异常告警。建议记录抓取成功率、解析缺失率、人工复核通过率及投递失败率;不要用页面演示数据宣称覆盖率或准确率。

技术参考

配套发布文案

公众号导读

招标监测不是把搜索结果转发一遍。本文用一个可运行的离线原型,拆解来源登记、公告版本、目标筛选和邮件摘要四个环节。客户可以设置地区、关键词和预算门槛,每条信息都给出命中或排除原因;预算缺失进入待复核,更正与撤回必须单独追踪。附Python代码、数据结构、交互演示和测试用例。当前为技术方案与离线演示,真实采购来源和邮件服务需另行接入。

朋友圈摘要

从“搜到公告”到“找到适合客户的项目”,中间还缺规则判断、去重和证据。我们整理了一套招标监测技术方案:可配置目标、可解释命中、可预览邮件,并附代码与演示页面。

配图建议:架构图用于说明流程,交互页面图用于说明配置与结果。发布时保留“离线演示”与样本口径。