Get Offer 秋招投递助手插件的实现

2651 字
13 分钟
Get Offer 秋招投递助手插件的实现

重复填网申信息实在是非常烦,并且投递后的信息管理需要额外使用飞书,于是vibe-coding了一个投递工具,在ai 完成后单独进行学习和消化。 github连接:https://github.com/put4o/get-offer-assistant

网申助手的一键填写是怎么实现的#

网申时最重复的工作,就是把姓名、电话、学校、实习经历和项目经历反复填写到不同公司的招聘网站中。

我做的网申助手允许用户提前保存一份个人资料。进入招聘页面后,点击“一键填写”,插件会自动识别页面字段,并把个人资料写入对应位置。

这个功能看起来像是简单的复制粘贴,但真正实现时主要要解决三个问题:

  1. 如何判断网页上的输入框代表什么;
  2. 如何把输入框与个人资料准确对应;
  3. 如何让招聘网站真正接受插件写入的内容。

一、一键填写的整体流程#

一次完整的自动填写过程可以分为五步:

读取个人资料
扫描当前页面的表单控件
判断每个控件对应的资料字段
处理重复经历和动态表单
写入内容并触发网页事件

用户点击按钮后,插件先从浏览器本地读取已经保存的个人资料,然后扫描页面中的输入框、文本域、下拉框和文件上传控件。

识别完成后,每个网页控件都会得到一个业务类型,例如姓名、手机号、学校、专业、公司、岗位或项目描述。插件再根据这些业务类型,从个人资料中取出对应值并写入网页。

二、如何识别网页字段#

不同招聘网站没有统一的字段命名规范。同一个姓名字段,可能叫 namefullNamerealName,也可能没有明确名称,只在输入框上方显示“申请人姓名”。

因此,字段识别不能只看输入框名称,而要综合多种信息:

  • 字段名称和编号;
  • 输入框类型;
  • 占位提示;
  • 自动填充属性;
  • 与输入框关联的标签文字;
  • 父容器中的业务名称;
  • 字段所在的表单模块。

例如,一个输入框自身可能没有任何有意义的名称,但它所在的容器写着“毕业院校”,插件仍然可以将它识别为学校字段。

对于日期字段,还要结合模块上下文判断。同样是“开始时间”,出现在教育经历中代表入学时间,出现在实习经历中代表入职时间,出现在项目经历中则代表项目开始时间。

三、字段如何与个人资料对应#

插件不会直接保存网页字段名称,而是先定义一组统一的业务字段,例如:

业务字段可能出现的网页名称
姓名name、fullName、realName、申请人姓名
手机号phone、mobile、tel、联系方式
邮箱email、mail、电子邮箱
学校school、university、毕业院校
专业major、specialty、所学专业
公司company、employer、工作单位
岗位position、jobTitle、职位名称
项目名称projectName、projectTitle、项目名称

扫描网页时,插件把字段名称、标签和上下文进行标准化处理,例如拆分驼峰、去掉下划线、统一大小写和空格,然后与这些业务字段的关键词进行匹配。

匹配结果带有置信度,而不是简单判断“是”或“不是”。字段类型明确、名称完全一致时,置信度较高;只有模糊关键词或上下文时,置信度较低。只有超过阈值的结果才会自动填写。

这种方式可以避免一些常见误判。例如,不能因为 projectName 中包含 name,就把它识别成个人姓名;也不能因为某个字段包含 id,就把它当成身份证号。对于 name、id、title 这类歧义较大的短词,必须要求更严格的匹配条件,并优先判断“项目名称”“公司名称”等更具体的含义。

如果本地规则无法确定字段类型,可以把字段名称、标签和占位提示交给 AI 做一次语义分类。AI 只负责返回字段属于哪一种业务类型,不直接修改网页。最终结果仍要经过有效性检查,无法判断的字段保持空白。

四、教育、实习和项目经历如何对应#

姓名和手机号只有一个值,比较容易填写。教育、实习和项目经历则是多条记录,页面中可能重复出现相同类型的字段。

插件按照字段在页面中的出现顺序进行对应:

  • 第一个学校字段对应第一段教育经历;
  • 第二个学校字段对应第二段教育经历;
  • 第一个公司字段对应第一段实习经历;
  • 第二个公司字段对应第二段实习经历。

专业、学历、岗位、描述和日期分别维护自己的顺序,从而保证同一条经历中的信息落到同一行。

在填写前,还要先检查页面是否有足够的经历行。假设用户保存了三段实习经历,而页面默认只显示一行,插件会先找到“添加”按钮,补足到三行,等待页面生成新控件,然后重新扫描并填写。

日期范围需要单独处理。很多网站把开始和结束日期放在同一个“起止时间”组件中,两个输入框没有独立名称。插件会根据它们在组件中的左右位置判断开始和结束,并结合所在模块选择教育、实习或项目日期。

部分日期组件会立即校验“开始时间不能晚于结束时间”。为了避免中间状态触发错误,填写时通常先写结束时间,再写开始时间。

五、如何让网页真正接收填写结果#

直接修改输入框的值,在普通网页中可能有效,但在 React、Vue 等框架构建的招聘网站中经常失败。

这些网站不仅保存输入框当前显示的文字,还在框架内部维护一份表单状态。如果插件只改变页面上的值,可能出现以下问题:

  • 页面显示已经填写,提交时却提示为空;
  • 输入框失去焦点后内容消失;
  • 表单校验没有执行;
  • 页面重新渲染后恢复成旧值。

因此,插件写入时会使用浏览器原生的值更新方式,并模拟用户输入过程中产生的事件,包括输入、内容变化和失去焦点等。这样网页框架才能更新内部状态,并执行原有的校验逻辑。

写入完成后还要读取控件的最终状态,确认网页是否真的接受了目标值。只有确认成功,才能把这个字段计入已填写数量。

六、下拉框和文件上传的处理#

原生下拉框可以直接遍历所有选项,根据选项值和显示文字进行匹配。例如,个人资料中保存的是“本科”,网页选项可能显示“大学本科”,可以通过标准化和部分匹配找到最接近的候选项。

自定义下拉框则不能直接设置值。它通常需要先点击控件,等待选项列表出现,再找到目标选项并模拟鼠标点击。选择完成后还要检查页面显示结果,确认组件已经更新。

简历上传也不是填写文件路径。插件会把本地保存的简历内容重新还原成浏览器文件对象,再模拟用户选择文件,并触发网页的文件变化事件。整个过程在本地完成,不需要经过额外的中转服务器。

七、动态页面为什么要重复扫描#

现代招聘网站的表单经常在运行过程中变化。新增经历、切换学历类型或选择某个选项后,页面可能插入新的字段,也可能销毁旧控件并重新创建。

所以插件会监听页面结构变化。当发现新的输入控件时,重新执行字段识别。正式填写前,在补足经历行之后也必须再次扫描,不能继续使用之前保存的页面元素。

这一步解决了很多“第一次能填,新增一行后就失效”的问题。

八、规则与 AI 如何配合#

一键填写以本地规则为主,AI 只作为补充。

姓名、手机号、邮箱等明确字段优先由规则识别,这样速度快、没有调用成本,结果也更稳定。只有字段命名复杂、规则置信度不足时,才使用 AI 判断字段语义。

AI 返回结果后仍然需要程序校验,而且不会主动覆盖网页中已经存在的内容。无法确定时保持空白,比填写错误的信息更安全。

对于一键填写后剩余的空白字段,还可以让用户框选一个页面区域,由 AI 根据个人资料进行补填。框选功能只收集区域内仍为空的字段,不处理已有值,也不会自动提交表单。

总结#

网申助手的一键填写并不是简单地把一组字符串写进网页,而是一条完整的处理链路:

  1. 从页面属性、标签和模块上下文中识别字段;
  2. 将不同网站的字段统一映射到个人资料模型;
  3. 按顺序处理多段教育、实习和项目经历;
  4. 为动态表单补足行数并重新扫描;
  5. 模拟真实输入事件,让网页框架接受新值;
  6. 对规则无法判断的字段使用 AI 兜底。

其中最重要的原则是:高置信度字段自动填写,无法确认的字段保持空白,最终提交前由用户检查。这样才能在提高填写效率的同时,尽量避免自动化带来的错误。

Get Offer 秋招投递助手插件的实现
https://putao.ink/posts/tools/get-offer-秋招投递助手/
作者
葡萄成熟时
发布于
2026-08-02
许可协议
CC BY-NC-SA 4.0

文章目录