欢迎光临
我们一直在努力

Seed-2.1-pro 择校平台:官网表格清洗、简章截图识别到产品上线全链路

考研择校最耗时间的环节,往往不是做决策,而是把散落在官网表格、PDF 与简章截图里的信息凑成一张可横向比较的表。一所院校一份招生目录,十所院校就是十种表头结构。

常规做法在这里明显不够用:写死选择器的爬虫经不起年年改版,OCR 只能出纯文本还得二次解析,人工复制粘贴又慢又容易抄错年份。确定性的代码搞不定版式多变的图片,纯靠模型又守不住字段精度。

本文分享一套可直接跑通的落地方案:pandas 表格清洗 + Seed-2.1-pro 多模态读图 + FastAPI 检索接口与筛选前端,可直接落地。

一、痛点:择校数据散落在表格与截图里

把考生卡住的地方先摆出来,一共是三处信息断层:

  • 官网表格零散:招生目录与复试线以 Excel、PDF 分发,字段名和表头位置每年都在变。
  • 关键数据是图片:报录比、复试名单常以截图形式贴在通知里,无法直接检索和比对。
  • 人工比对成本高:横向对比十几所院校,光是复制粘贴就要耗掉大半个下午。

核心结论: 择校平台的第一性问题不是推荐算法,而是把异构信息收敛成可比的结构化字段。

在这里插入图片描述

二、链路:官网数据到可查服务的四段流水

整条链路拆成四段流水,每一段只负责一件事,先看全局:

官网表格 → pandas 清洗 → Seed-2.1-pro 读图 → 字段合并校验 → 检索接口 → 筛选前端

  • 采集段:只负责拿到原始 Excel 与截图,不做任何业务判断,方便替换来源。
  • 抽取段:表格走确定性代码,图片走多模态模型,两条通道并行互不阻塞。
  • 服务段:合并后的记录落进 SQLite,由 FastAPI 统一暴露查询接口。
  • 呈现段:静态页面只调接口,完全不接触模型与清洗逻辑,前端可独立迭代。

核心结论: 把不确定性最大的读图环节单独隔离,其余三段都能用普通工程手段写单测。

三、表格抽取:官网 Excel 清洗成结构化记录

官网 Excel 的表头位置年年变,先做结构探测再取数:

  • 表头探测:用关键字匹配定位真实表头行,避免把行号写死在代码里。
  • 类型收敛:招生人数转数值型,非数字行在读入阶段直接丢弃。

下面这段代码用 pandas 定位含“专业代码”的表头,向下取数并统一列名,适配常见招生目录表:

import pandas as pd

def load_major_table(path):
df = pd.read_excel(path, header=None)
mask = df.astype(str).apply(lambda r: r.str.contains('专业代码').any(), axis=1)
hdr = int(mask.idxmax()) # 定位真实表头行
body = df.iloc[hdr + 1:].reset_index(drop=True)
body.columns = ['major_code', 'major_name', 'plan', 'subject', 'line']
body = body.dropna(subset=['major_code'])
body['plan'] = pd.to_numeric(body['plan'], errors='coerce')
return body.dropna(subset=['plan'])

先探测表头、再取数、最后做类型转换,脏行在读入阶段就被剔除。

核心结论: 表格通道追求 100% 确定性,任何一行进不了 schema 就地报错,不带病入库。

在这里插入图片描述

四、截图识别:多模态模型读出招生字段

简章截图交给 Seed-2.1-pro,让它按固定模板吐字段:

  • 提示词锁格式:明确列出字段名并要求缺失填 null,禁止输出解释性文字。
  • 温度压到 0.1:抽取任务不需要创造性,低温度能显著降低字段漂移。
  • 单图单请求:一张截图对应一次调用,失败可单独重试且不污染其他记录。

下面这段代码完成图片 base64 编码、提示词组装与返回解析,可直接对接 Seed-2.1-pro 的 OpenAI 兼容端点:

import base64, json, requests

def read_admission_shot(img_path, api_key):
b64 = base64.b64encode(open(img_path, 'rb').read()).decode()
content = [
{'type': 'image_url',
'image_url': {'url': 'data:image/png;base64,' + b64}},
{'type': 'text',
'text': '提取院校名称、专业代码、复试分数线、招生人数,'
'只输出 JSON,缺失字段填 null'}
]
payload = {'model': 'seed-2.1-pro',
'messages': [{'role': 'user', 'content': content}],
'temperature': 0.1}
r = requests.post('https://ark.example.com/api/v3/chat/completions',
headers={'Authorization': 'Bearer ' + api_key},
json=payload, timeout=60)
return json.loads(r.json()['choices'][0]['message']['content'])

低温度 + JSON 约束 + 单图单请求 = 可直接入库的字典。

五、字段对齐:合并表格行与图片抽取结果

两条来源拿到同名字段时,必须有一套可执行的合并顺序:

表格主键定位 → 图片补空缺 → 冲突打标 → 人工复核队列

字段表格来源图片来源合并策略
院校名称 表内抬头 简章页眉 一律以表格为准
复试分数线 分数列 模型识别值 不一致则标 need_review
招生人数 计划列 简章正文 表格缺失时才用图片补齐
专业代码 首列 章节标题 长度不足 4 位直接判失败
  • 主键优先:院校代码加专业代码构成主键,图片内容只作为属性补充。
  • 冲突不覆盖:两侧数值不一致时不自动取舍,标记留给人工复核流程。

核心结论: 合并规则写死在代码里,比让模型临场判断更可控、更可回溯。

六、规则校验:给分数与招生人数加一道闸门

模型会幻觉,规则层必须在入库前拦下脏数据:

下面这段校验函数在记录入库前统一执行,返回状态与错误原因,可挂到任意批处理管道:

def validate(rec, year=2025):
errs = []
line = rec.get('line') or 0
if not (150 <= line <= 400):
errs.append('分数线超出合理区间')
if (rec.get('plan') or 0) > 1000:
errs.append('招生人数异常')
if rec.get('year') != year:
errs.append('数据年份不符')
rec['status'] = 'pass' if not errs else 'review'
rec['errors'] = errs
return rec

  • 区间校验:复试线落在 150~400 之外,基本可判定为识别或抄录错误。
  • 状态分流:通过的记为 pass,异常的记为 review 并附具体错误原因。

规则层兜底,模型输出永远不直接进库。

在这里插入图片描述

七、检索接口:按分数地区专业返回候选院校

检索接口只认结构化字段,四个参数决定一次查询:

参数类型示例作用
score int 365 按线差排序的考生初试分
region str 华东 限定院校所在大区
major str 0854 专业代码前缀匹配
limit int 10 返回条数,默认 10
  • 线差排序:用考生分数减院校复试线,按差值从高到低排,天然分出保底与冲刺。
  • 前缀匹配:专业代码支持前缀检索,0854 可一次召回整个计算机专硕大类。

核心结论: 接口参数越少越稳定,复杂度留在排序策略里而不是暴露给调用方。

八、前端筛选:让考生三步找到目标院校

页面设计成三步筛选,考生完全不需要理解数据结构:

  • 第一步填分数:输入初试总分,即时显示可冲击院校数量,给出正反馈。
  • 第二步选范围:地区与专业代码用下拉多选,避免自由输入带来的空结果。
  • 第三步看卡片:每张卡片展示复试线、招生人数、线差与数据来源年份。

交互只暴露结果,字段复杂度全部留在后端。

在这里插入图片描述

九、部署启动:一键拉起接口与静态页面

部署拆成后端接口与静态页面两条进程,各自独立做健康检查:

下面这段脚本在一台干净的 Linux 机器上完成依赖安装、接口启动、静态资源托管与连通性验证:

pip install -r requirements.txt
export SEED_API_KEY=xxxx
uvicorn server:app –host 0.0.0.0 –port 8000 &
python -m http.server 5173 –directory web
curl -s http://127.0.0.1:8000/health

  • 密钥外置:API Key 只走环境变量,禁止写进仓库或前端 JS。
  • 健康探针:/health 返回 200 才放行前端,避免白屏后无从排查。

接口与页面分离启动,健康检查通过即视为服务可访问。

十、排错验收:常见故障与定位路径

上线后的问题集中在四类,按现象到路径逐一排查:

现象可能原因定位动作
表格读入为空 表头行判断错位 打印 df.head(15) 核对关键字
读图接口超时 单图体积过大 压到 1MB 以内再重试
分数线全为 null 提示词未锁 JSON 检查返回是否被包成自然语言
检索返回空 专业代码写成中文名 改用代码前缀替代名称查询
  • 复现优先:先用一条真实记录跑通全流程,再改代码,避免在猜测中调试。
  • 留痕入库:每次抽取都保存原始图片路径与模型原始返回,便于事后回溯。

核心结论: 排错表直接贴进仓库 README,比口头经验更耐用。

在这里插入图片描述

结语

这条链路的价值在于分工清晰:pandas 负责确定性的表格,Seed-2.1-pro 负责版式多变的图片,规则层负责最后一道闸门,三者各司其职,任何一环失效都能被定位到具体日志。换一个年份的招生数据,只需替换输入文件,清洗与校验代码基本不动。

产品化之后,它不再是一个数据脚本,而是能被前端调用、能被运维监控、能被考生直接使用的可运行服务,后续接上收藏、对比与志愿表生成也有清晰的挂载点。

数据来源再乱,只要经过“抽取—校验—合并”三道工序,都能变成可检索的择校决策依据。

赞(0)
未经允许不得转载:171主机测评 » Seed-2.1-pro 择校平台:官网表格清洗、简章截图识别到产品上线全链路
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址