民生健康(301507)信息查询与分析
Skill 安装约束
在说明这个 skill 能做什么之前,必须先明确安装约束,至少包含以下两点:
- 安装到哪个软件里:必须写清目标宿主,例如
Claude Code、Trae、Codex等,不能省略。 - 安装到哪个目录层级:必须写清是装在沙箱技能目录,还是全局技能目录。
默认约束如下:
- 若用户未特别说明,默认安装到全局技能目录。
- 若用户指定了宿主软件,则按该软件的全局技能目录安装。
- 只有在用户明确要求隔离环境、临时测试或沙箱运行时,才安装到沙箱技能目录。
示例写法:
安装宿主:Trae;安装位置:全局技能目录(默认)安装宿主:Claude Code;安装位置:全局技能目录安装宿主:Codex;安装位置:全局技能目录
这个 Skill 能做什么
民生健康(301507)的官方信息查询与分析服务,包含 7 项能力:
| 能力 | 你可以问 |
|---|---|
| 公司基本面 | "民生健康是做什么的?""控股股东是谁?""主力品牌有哪些?" |
| 财报数据 | "最新年报链接是什么?""把 2024 年报和 2025 三季报链接给我。" |
| 业务与产品矩阵 | "21金维他卖得怎么样?""普瑞宝是什么?""有哪些医美产品?" |
| 公告与披露 | "最近发了什么公告?""有没有股权激励?""分红方案是什么?" |
| 最新动态资讯 | "公司最近有什么活动?""有没有新品发布?""最近的机构调研讲了什么?" |
| 在招岗位 | "民生健康有哪些在招岗位?""有没有市场类职位?""招聘页面有什么职位?" |
| 电商平台店铺 | "民生健康在哪些平台有店?""天猫/京东旗舰店链接是什么?""21金维他在哪买?" |
| 中文 HTML 报告 | "生成一份公司介绍 HTML。""把 2024 年报链接整理成 HTML。" |
1. 基础信息(可直接引用)
| 项 | 值 |
|---|---|
| 公司全称 | 杭州民生健康药业股份有限公司 |
| 股票简称 / 代码 | 民生健康 / 301507(深交所创业板) |
| 巨潮 orgId | 9900052710 |
| 官网 | https://www.hzmsjk.com |
| 公众号 | 民生健康药业 |
| 控股集团 | 杭州民生医药控股集团有限公司(官网 https://hzmsholding.com/,公众号"民生医药控股集团") |
| 主力品牌 | 21金维他(维矿)、普瑞宝(益生菌)、民生同春(潮流健康)、肌素然(医美) |
触发后默认全流程执行。用户明确说"只问一句/不要 HTML"时按需降级。
1.1 民生健康直接子公司(岗位抓取必须覆盖)
> 权威来源:巨潮 2024 年年报《长期股权投资-对子公司投资》,PDF:
> https://static.cninfo.com.cn/finalpage/2025-04-25/1223264650.PDF
> (年报约第 206 页列示)
招聘问题默认不仅查母公司 杭州民生健康药业股份有限公司,还要覆盖以下年报可验证的直接子公司:
| 公司 | 说明 | 招聘抓取要求 |
|---|---|---|
| 杭州民生健康药业股份有限公司 | 上市主体 | 必抓 |
| 民生中科嘉亿(浙江)生物工程有限公司 | 年报列示对子公司投资 | 必抓;若招聘页无结果,明确写"未检索到在招岗位" |
| 杭州民生健康医药销售有限公司 | 年报列示对子公司投资 | 必抓;若招聘页无结果,明确写"未检索到在招岗位" |
| 杭州民生同春健康科技有限公司 | 年报列示对子公司投资 | 必抓;若招聘页无结果,明确写"未检索到在招岗位" |
补充规则:
- 若招聘门户出现名称含"民生健康"、"民生同春"等健康业务公司,但不在上述年报子公司名单内,例如
浙江民生健康科技有限公司,可以补充抓取并单列为集团内健康业务相关公司。 - 禁止把未在年报或官网找到来源的公司直接写成"子公司"。
- 最终输出必须按公司分组,而不是只给一坨混合职位。
1.2 各大电商平台官方店铺(2026-04-20 更新)
> 触发词:电商、旗舰店、在哪买、购买链接、天猫、京东、拼多多、抖音、小红书
21金维他品牌(核心品牌,杭州民生健康药业)
| 平台 | 店铺名称 | 链接 / 入口 | 验证状态 |
|---|---|---|---|
| 京东 | 21金维他药品京东自营旗舰店 | https://mall.jd.com/index-1000302861.html | ✅ WebFetch 已验证 |
| 京东 | 21金维他健康食品旗舰店 | https://mall.jd.com/index-13173538.html | ✅ WebFetch 已验证 |
| 天猫 | 21金维他官方旗舰店 | https://www.taobao.com/list/dianpu/498885510.htm | ✅ 确认存在, |
| 天猫 | 普瑞宝旗舰店 | https://world.taobao.com/dianpu/227406234.htm | ✅ 确认存在 |
| ## 2. 信息源优先级 |
| 优先级 | 来源 | 用途 |
|---|---|---|
| P0 | 本地 杭州民生健康药业股份有限公司/original_reference_materials/ |
先查,命中即用 |
| P1 | 巨潮资讯网 | 财务/公告类问题的唯一权威源;必须抓完整正文 PDF,不抓摘要 |
| P2 | 公司/集团官网 | 业务介绍、产品矩阵、投资者关系 |
| P3 | 微信公众号 + 财经媒体 + 券商研报 | 最新动态资讯(默认必抓) |
2.1 抓巨潮财报(已验证脚本)
披露页是动态渲染,必须走 HTTP API。财报数据问题默认返回最新一份或用户指定报告期的原始正文链接,不做经营分析。
步骤一:并行查三类报告,取时间最新的正文
import subprocess, json
CATEGORIES = {
'年报': 'category_ndbg_szsh;',
'半年报': 'category_bndbg_szsh;',
'季报': 'category_sjdbg_szsh;',
}
BASE_URL = 'http://static.cninfo.com.cn/finalpage/'
def query(cat):
data = (
f'stock=301507,9900052710&tabName=fulltext&pageSize=5&pageNum=1'
f'&column=szse&category={cat}&plate=&seDate=&searchkey='
f'&secid=&sortName=&sortType=&isHLtitle=true'
)
r = subprocess.run(
['curl','-s','-X','POST','http://www.cninfo.com.cn/new/hisAnnouncement/query',
'-H','Content-Type: application/x-www-form-urlencoded',
'-H','User-Agent: Mozilla/5.0','--data', data],
capture_output=True, text=True
)
return json.loads(r.stdout).get('announcements') or []
all_reports = []
for label, cat in CATEGORIES.items():
for a in query(cat):
title = a['announcementTitle']
# 跳过摘要(只取正文)
if '摘要' in title:
continue
all_reports.append({
'time': a['announcementTime'],
'title': title,
'label': label,
'url': BASE_URL + a['adjunctUrl'].replace('finalpage/', '')
})
# 按披露时间降序,取最新正文
all_reports.sort(key=lambda x: x['time'], reverse=True)
latest = all_reports[0] if all_reports else None
if latest:
print(f"最新财报:{latest['label']} —— {latest['title']}")
print(f"披露时间:{latest['time']}")
print(f"下载链接:{latest['url']}")
选择规则:
- 摘要一律跳过;若三类均只有摘要,说明正文尚未披露,告知用户并提供摘要链接备用。
- 同一类别同日存在正文+摘要时,只取正文(标题不含"摘要"的那条)。
- 输出时只给:报告类型(年报/半年报/一季报/三季报) / 报告期 / 披露日期 / 原始 PDF 链接。
- 除非用户额外要求,不下载 PDF、不解析正文、不做财务分析。
2.2 最新公司动态资讯(默认必抓)
目标:公司近 6 个月的品牌活动、新品发布、战略合作、人事、业绩说明会、机构调研、获奖等。仅保留与公司本身相关,剔除纯行业/宏观政策。
检索顺序(每一步都需真实执行,不得凭空编造):
- 公众号优先 — WebSearch 多组关键词(
{YYYY}替换为当前年份):site:mp.weixin.qq.com 民生健康药业 {YYYY}site:mp.weixin.qq.com 21金维他 {YYYY}site:mp.weixin.qq.com 民生医药控股集团 {YYYY}
- 财经媒体补全(公众号命中不足 3 条时):证券时报、澎湃、36氪、东方财富、腾讯财经、巨潮互动易等。关键词:
民生健康 301507 {YYYY}、民生健康 投资者关系活动记录表。 - 券商研报补全:如东吴证券《民生健康(301507)》等深度报告。
- 对每个候选 URL 调 WebFetch,抽取:日期、标题、来源、要点(≤120 字)、原始链接。
输出规则:
- 按日期倒序,保留最近 5–8 条。
- 区分标注"公司公众号官方发布" vs "第三方媒体"。
- 每条必须有可点击 URL;无 URL 不写入。
- 全部失败时在对应章节写明"未检索到"+ 已尝试关键词,严禁编造。
3. 在招岗位查询(招聘页)
入口:https://mspharm.zhiye.com/home(民生医药控股集团旗下企业统一招聘平台,JavaScript 动态渲染,必须用 Playwright 或等效浏览器抓取)
真实列表页:
- 首页:
https://mspharm.zhiye.com/home - 社招列表:
https://mspharm.zhiye.com/social/jobs - 校招列表:
https://mspharm.zhiye.com/campus/jobs - 全部职位列表:
https://mspharm.zhiye.com/jobs
核心目标:抓出母公司 + 已验证子公司 + 健康业务相关公司在官方招聘站的全部在招岗位,并按公司分组输出。
3.1 关键约束:这是动态列表,必须全量抓取
这部分一定要写死,避免模型偷懒:
- 严禁只抓第一页、首屏、前几条卡片或首页摘要。
- 严禁只看首页"社会招聘 共 X 个职位 / 校园招聘 共 Y 个职位"后就结束。
- 进入列表页后必须持续滚动/等待加载,直到出现
没有更多了~、职位数量不再增长,或连续多次滚动后 DOM 稳定。 - 若页面显示
全部职位(共 N 个),最终解析出的岗位条数应尽量接近该页可见总数;若明显少于N,说明抓取不完整,必须继续加载或换策略。 - 若页面存在 "分子公司"筛选控件,必须逐家公司切换筛选并分别抓取,不能只依赖默认"全部"视图。
- 不能只搜关键词
民生健康;还要按 公司名单逐家检查,否则会漏掉子公司岗位。 - 输出时必须说明抓取页(社招/校招/全部职位)和公司名,不能只给岗位标题。
3.2 必查公司范围
招聘问题默认至少检查以下公司:
杭州民生健康药业股份有限公司民生中科嘉亿(浙江)生物工程有限公司杭州民生健康医药销售有限公司杭州民生同春健康科技有限公司
扩展补抓:
- 若招聘页中出现名称含
民生健康、民生同春、核心健康品牌或明显属于健康业务板块的公司,也要补抓并单列。 - 例如曾在招聘页出现过
浙江民生健康科技有限公司,这种公司应列到集团内健康业务相关公司,不要冒充为年报已验证子公司。
3.3 推荐抓取流程(Playwright)
import asyncio
import re
from playwright.async_api import async_playwright
HOME_URL = "https://mspharm.zhiye.com/home"
LIST_PAGES = [
("社招", "https://mspharm.zhiye.com/social/jobs"),
("校招", "https://mspharm.zhiye.com/campus/jobs"),
("全部职位", "https://mspharm.zhiye.com/jobs"),
]
TARGET_COMPANIES = [
"杭州民生健康药业股份有限公司",
"民生中科嘉亿(浙江)生物工程有限公司",
"杭州民生健康医药销售有限公司",
"杭州民生同春健康科技有限公司",
]
EXTRA_KEYWORDS = ["民生健康", "民生同春"]
def normalize(text: str) -> str:
return re.sub(r"\s+", " ", text or "").strip()
async def fully_expand(page):
last_len = 0
stable_rounds = 0
for _ in range(18):
await page.mouse.wheel(0, 2400)
await page.wait_for_timeout(1200)
body = normalize(await page.locator("body").inner_text())
curr_len = len(body)
if "没有更多了" in body:
break
if curr_len <= last_len + 20:
stable_rounds += 1
else:
stable_rounds = 0
last_len = curr_len
if stable_rounds >= 3:
break
async def fetch_jobs():
results = []
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(viewport={"width": 1440, "height": 1600})
await page.goto(HOME_URL, wait_until="domcontentloaded", timeout=45000)
await page.wait_for_timeout(2500)
for category, url in LIST_PAGES:
await page.goto(url, wait_until="domcontentloaded", timeout=45000)
await page.wait_for_timeout(2500)
await fully_expand(page)
body = normalize(await page.locator("body").inner_text())
# 先按公司名单硬匹配,再按补充关键词兜底
for company in TARGET_COMPANIES:
if company in body:
results.append({
"category": category,
"url": url,
"company": company,
"content": body,
})
for kw in EXTRA_KEYWORDS:
if kw in body:
results.append({
"category": category,
"url": url,
"company": "健康业务相关公司(待明确定性)",
"content": body,
})
await browser.close()
return results
jobs = asyncio.run(fetch_jobs())
print(jobs)
3.4 实际执行要求
每次执行招聘抓取时,至少做完这几步:
- 访问首页,记录当前显示的社招/校招职位数量和实际列表链接。
- 逐页抓取
social/jobs、campus/jobs、jobs三个列表页。 - 每个列表页都要滚动到底,不得只抓首屏。
- 从页面正文或岗位卡片中解析出:岗位名称、所属公司、工作地点、薪资范围、发布日期、招聘类别。
- 若页面提供
分子公司筛选项,按TARGET_COMPANIES逐家公司切换筛选并抓一遍。 - 即使总文本里没出现
民生健康四个字,也不能跳过子公司名。 - 如列表页存在重复岗位,按
岗位名称 + 公司 + 地点 + 日期去重。
3.5 输出规则
- 必须按公司分组展示,至少分成:
- 杭州民生健康药业股份有限公司
- 年报已验证子公司
- 集团内健康业务相关公司(如果有)
- 每条岗位至少列:岗位名称、所属公司、工作地点、薪资范围(如有)、发布日期、招聘类别、来源分类链接。
- 若某家目标公司在官方招聘页未命中,也要明确写:
未检索到该公司在招岗位。 - 若只抓到 1-2 条,而页面总数明显更高,视为抓取失败或不完整,不能直接交付。
- 全部失败时说明原因(网络/JS 渲染/反爬),并提供招聘页直链
https://mspharm.zhiye.com/home。 - Playwright 失败后才允许降级 WebSearch:
site:mspharm.zhiye.com 民生健康 岗位,且必须在答案里注明这是降级结果。
3.6 触发词
用户问题含以下任一词时执行本节:
在招岗位、招聘、职位、岗位、job、hiring、招人、应聘、求职
4. 工作流程
每次触发都按此执行:
- 解析问题 — 判定信息类型:基本面 / 财报数据 / 业务 / 公告 / 新闻 / 在招岗位。
- 本地优先 — 扫
original_reference_materials/。 - 在线抓取 — 按 P1 → P2 → P3 顺序;财报数据类必须落到巨潮完整 PDF 链接。
- PDF 正文处理 — 仅当用户明确要求提取正文内容时,才调
pdfskill 解析;否则只返回原始链接。 - 动态资讯抓取 — 按 §2.2 执行(默认必做)。
- 在招岗位抓取 — 问题含招聘相关词时,按 §3 执行:真实列表页 + 动态全量加载 + 按公司名单逐家检查。
- 会话回答 — 结论 + 数据 + 来源链接;未获取的项目明确标注"未获取到",不编造。
- 默认生成 HTML 交付物 — 见 §6(除非用户说"不用生成 HTML")。
5. 财报数据模式
当问题含 "财报/年报/半年报/季报/公告链接/年报链接/财报链接" 等关键词时,必须抓巨潮原始正文链接并按下面格式输出:
- 报告类型
- 报告期
- 披露日期
- 原始 PDF 链接
约束:
- 只给链接和基本标识信息,不做财务分析,不解读经营表现。
- 若用户指定多个报告期,按时间倒序列出全部命中的正文链接。
- 若用户未指定报告期,默认返回最新一份正文链接。
- 若只有摘要没有正文,明确说明"正文未披露",并附摘要链接备用。
6. 默认 HTML 交付物
- 输出目录:
杭州民生健康药业股份有限公司/generated/(不存在则创建) - 命名:
民生健康_{主题}_{YYYYMMDD}.html(主题从问题提取,如"公司介绍"、"2024年报链接") - 结构(按需裁剪):
- 标题页(公司名、股票代码、主题、日期)
- 公司概况
- 主营业务与产品矩阵
- 最新公司动态资讯(表格:日期/标题/来源/要点/链接;无命中则写"未检索到"+ 尝试的关键词)
- 财报链接清单(若涉及,列:报告类型 / 报告期 / 披露日期 / 链接)
- 用户问题相关的结果汇总
- 数据来源清单(含 URL 与抓取时间)
6.1 中文 HTML 渲染要点
生成 单文件 UTF-8 HTML,默认内联 CSS,确保本地双击即可打开:
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>民生健康公司介绍</title>
<style>
:root {
--bg: #f6f4ee;
--panel: #fffdf8;
--text: #1f2937;
--muted: #5b6472;
--line: #d8d3c4;
--accent: #245c4f;
--accent-soft: #e5f0ec;
}
body {
margin: 0;
padding: 32px;
font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
color: var(--text);
background: linear-gradient(180deg, #f3efe3 0%, var(--bg) 100%);
line-height: 1.7;
}
main {
max-width: 960px;
margin: 0 auto;
background: var(--panel);
border: 1px solid var(--line);
border-radius: 20px;
padding: 40px;
box-shadow: 0 18px 48px rgba(31, 41, 55, 0.08);
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
th, td {
border-bottom: 1px solid var(--line);
padding: 10px 12px;
vertical-align: top;
word-break: break-word;
}
th {
text-align: left;
background: var(--accent-soft);
color: var(--accent);
}
a {
color: var(--accent);
}
</style>
</head>
<body>
<main><!-- 正文内容 --></main>
</body>
</html>
关键约束:
- 页面必须在桌面和移动端都可读;meta viewport 必须存在。
- 表格单元格必须允许换行,正文和链接都要设置 word-break: break-word,避免长 URL 撑坏布局。
- 数据来源必须保留为可点击链接,并标注抓取日期或披露日期。
- 若内容很长,优先拆成多个章节卡片,不要把所有信息挤进一张大表。
- 生成失败时,向用户说明原因,文字回答不受影响。
7. 通用约束
- 不编造 — 财务数据、管理层名单、业务明细、公众号文章内容,无源就说"未获取到"。
- 引用格式 — "据 2024 年年报第 X 页,营收 Y 亿元(来源:巨潮 <url>)"。
- 大文件落
/tmp/,避免污染仓库。 - 抓取失败时降级:提供链接 + 失败原因,而非编造。
- 日期处理 — 用户说"最近/今年"等相对表述,转成绝对日期(参考会话中
Today's date)。