k-skill 实战:naver-blog-research 技能实现 Naver 博客搜索、正文提取与图片下载(零 API Key)
2026/9/18 13:23:56 网站建设 项目流程

k-skill 实战:naver-blog-research 技能实现 Naver 博客搜索、正文提取与图片下载(零 API Key)

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

naver-blog-research 是 k-skill 技能库中面向韩语内容调研的轻量级技能,它让 AI Agent 仅凭python3标准库即可完成 Naver 博客搜索、单篇正文提取与图片本地下载,全程不需要任何 API Key。本文以其instruction.md为骨架,结合仓库内 4 个脚本源码与单元测试,完整讲解三个核心命令的参数用法、JSON 输出结构、底层实现原理与合规边界,读完即可在 k-skill CLI 中直接落地韩语博客调研工作流。

一、技能定位:这个 Skill 能做什么

naver-blog-research 的核心能力可以概括为三句话(源自其 instruction.md 的 What this skill does):

  • 搜索:检索 Naver 博客(블로그),输出结构化的 JSON 结果;
  • 阅读:读取单篇博客的原文本内容;
  • 下载:把正文中的图片下载到本地目录。

它的设计取舍非常有特点,也是它区别于一般爬虫脚本的关键:

  • 零依赖零密钥:不依赖任何第三方 Python 包,全部使用python3(3.8+)标准库完成 HTTP 请求与 HTML 解析;
  • 结构化输出:搜索结果、正文、图片列表都以 JSON 返回,方便 Agent 或下游程序直接消费;
  • 移动端直取正文:PC 版blog.naver.com是 iframe 嵌套结构,难以直接抓取,脚本会主动把 URL 转为移动版m.blog.naver.com,从而无 iframe 地直接提取正文;
  • CDN 定向下载:只允许从 Naver 博客图片 CDN 域名(blogfiles.naver.netpostfiles.pstatic.net)下载图片。

从 skill.json 的元数据可以看到,它被归类为category: researchlocale: ko-KRphase: v1,即面向韩国本土内容的调研型技能。

二、适用与不适用场景

什么时候用(When to use)

文档给出了几类典型触发场景,均是韩语内容调研的自然语言指令:

  • "네이버 블로그에서 결혼식 체크리스트 검색해줘"(帮我在 Naver 博客搜索婚礼清单)
  • "네이버 블로그 리서치 해줘"(帮我做 Naver 博客调研)
  • "한국 블로그에서 관련 정보 조사해줘"(帮我调查韩国博客上的相关信息)
  • "네이버 블로그 글 읽어줘"(帮我读这篇 Naver 博客文章)
  • "이 네이버 블로그 포스트에서 이미지 다운로드해줘"(帮我下载这篇 Naver 博客里的图片)
  • 在韩语内容调研中,需要 Google 之外补充 Naver 博客这一信源时

什么时候不要用(When not to use)

文档明确划定了使用边界,Agent 触发时应主动拒绝或改道:

  • 搜索 Naver 新闻、Cafe、지식iN(知识人)等其他非博客服务——本技能只处理博客域;
  • 大规模爬取/抓取(单个会话内数十次以上的请求)——本技能明确不适用;
  • 商业性数据采集。

三、前置条件

按文档要求,运行本技能需要:

  • 可用的互联网连接;
  • python33.8 及以上版本(标准库即可,无第三方依赖);
  • 技能目录scripts/内的 helper 脚本(即本仓库 packages/k-skill-cli/skills/naver-blog-research/scripts/ 下的 4 个文件)。

此外,实际调用依赖 k-skill CLI 执行环境。技能目录下的 SKILL.md 还提示:可以先运行npx -y @nomadamas/k-skill@0 instruct naver-blog-research获取完整指令,用npx -y @nomadamas/k-skill@0 files naver-blog-research查看随技能打包的 helper 文件清单。

四、脚本架构:4 个文件的分工

从 scripts 目录 看,技能由 3 个可执行脚本 + 1 个共享工具模块组成:

文件职责
naver_search.py调用 Naver 搜索页抓取博客搜索结果,输出结构化 JSON
naver_read.py读取单篇博客,提取标题、正文与图片 URL
naver_download_images.py从 CDN 下载图片到本地目录
_naver_http.py共享 HTTP 工具:SSL 上下文管理、Naver 域名校验、urlopen封装

这种"共享工具 + 三个功能入口"的结构保证了三处对 HTTP 行为的处理(尤其是 SSL 与域名白名单)完全一致,是阅读源码时值得借鉴的分层方式。

五、工作流 1:博客搜索(naver_search.py)

命令与参数

npx -y @nomadamas/k-skill@0 exec naver-blog-research scripts/naver_search.py -- "검색어" --count 10 --sort sim

参数表(继承自 instruction.md):

参数必填说明默认值
query搜索词-
--count返回结果数(最大 30)10
--sortsim(相关度)/ date(最新)sim
--timeout请求超时(秒)15

输出示例

{ "query": "결혼식 체크리스트", "total_results": 7, "results": [ { "title": "결혼식 체크리스트 총정리", "url": "https://blog.naver.com/user123/224212849946", "mobile_url": "https://m.blog.naver.com/user123/224212849946", "snippet": "결혼식 1주일 전에 반드시 확인해야 할...", "author": "user123" } ] }

每个结果条目同时包含 PC URL 与 mobile URL,author即博客作者 ID(从 URL 路径中解析),snippet为搜索摘要,便于 Agent 先概览再决定是否深入阅读。

源码级解析:请求参数与分页

查看 naver_search.py 可了解其底层实现:

搜索请求构造build_search_params,约 L46-L53):请求目标为https://search.naver.com/search.naver,核心查询参数包括:

  • ssc=tab.blog.all:锁定"博客"标签页;
  • sm=tab_jum(首页跳转)/tab_pge(翻页)两种模式;
  • start:起始结果序号,每页 15 条(RESULTS_PER_PAGE = 15);
  • nso:排序控制,sim对应so:r,p:all,a:all(按相关度),date对应so:dd,p:all,a:all(按日期倒序)。

结果解析parse_search_results):通过正则BLOG_ANCHOR_PATTERN(L31-L34)匹配形如blog.naver.com/{author}/{postId}的链接,并利用标题/摘要的 class 特征(如headline1body1)区分 title 与 snippet。值得注意的是,解析时会专门剔除"새 창 열림"(新窗口打开)这类可访问性隐藏标签,避免污染标题文本。

分页与去重search函数,L109-L150):count会被钳制在 1~30 之间;每页只取前 15 条,跨页请求之间time.sleep(0.5)限速;结果按 URL 去重,不足目标数量时继续翻页,直到取够或没有新结果为止。若首页就解析失败,会向 stderr 打印警告,提示 Naver HTML 结构可能已变化。

六、工作流 2:博客正文阅读(naver_read.py)

命令与参数

npx -y @nomadamas/k-skill@0 exec naver-blog-research scripts/naver_read.py -- "https://blog.naver.com/user123/224212849946"

参数表:

参数必填说明默认值
url博客文章 URL(PC 或移动版均可)-
--no-images输出中排除图片 URLfalse
--max-length正文最大字符数(0=不限)0
--timeout请求超时(秒)20

文档特别说明:即使传入 PC 版 URL,脚本也会自动转换为移动版 URL 再请求

源码级解析:移动版转换与正文提取

查看 naver_read.py:

URL 转换to_mobile_url,L53-L60):把https://blog.naver.com/...前缀替换为https://m.blog.naver.com/;若 URL 本身不是该形式,则用正则从任意 URL 中提取blog.naver.com/{id}/{postId}重组移动版地址。请求时使用 iPhone 版 User-Agent(L15-L18)。

正文区域定位extract_content_area,L115-L131):优先匹配se-main-container容器,依次回退到post_ctpostViewAreapost-view等 class,最后尝试id="viewTypeSelector"标记;找到后通过括号配平的_extract_div_block切出完整 div 块,并对 HTML 注释做了跳过处理。

文本清洗extract_text,L134-L148):先剔除<script><style><noscript>块,再把<br></p></div></li>等块级结束标签替换为换行,随后剥掉所有标签并做 HTML 实体反转义,最后规整空白行。

图片提取extract_images,L151-L182):仅接受来自三个 CDN 域(blogfiles.naver.netpostfiles.pstatic.netmblogthumb-phinf.pstatic.net)的图片,同时匹配data-lazy-src(懒加载)与src两种属性并按基础 URL 去重;对带_blur模糊后缀的缩略图会改写为?type=w800的高清版本,并附带alt文本。

输出结构read_blog,L185-L209):

{ "url": "https://m.blog.naver.com/user123/224212849946", "title": "결혼식 체크리스트 총정리", "content": "…正文文本…", "char_count": 1024, "images": [ { "url": "https://blogfiles.naver.net/...", "alt": "…" } ] }

--max-length生效时正文会被截断并追加...;若未找到正文区域,会输出warning字段提示 HTML 结构可能已变化。

七、工作流 3:图片下载(naver_download_images.py)

命令与参数

npx -y @nomadamas/k-skill@0 exec naver-blog-research scripts/naver_download_images.py -- --urls "url1,url2,url3" --output ./images/

也可以把naver_read.py的结果直接通过管道喂给它:

npx -y @nomadamas/k-skill@0 exec naver-blog-research scripts/naver_read.py -- "https://..." | npx -y @nomadamas/k-skill@0 exec naver-blog-research scripts/naver_download_images.py -- --output ./images/

参数表:

参数必填说明默认值
--urls逗号分隔的图片 URL 列表-
--output保存目录./naver-images/
--max最大下载数量10
--timeout请求超时(秒)15

源码级解析:管道读取、并发与安全

查看 naver_download_images.py:

  • stdin 管道read_urls_from_stdin,L180-L199):若未传--urls且 stdin 不是 TTY,会尝试把 stdin 作为 JSON 解析,支持三种形态——含images键的字典(即naver_read.py的输出)、URL 字符串数组、{"url": ...}对象数组。因此上一节的管道用法天然成立;
  • 并发下载download_images,L105-L150):用ThreadPoolExecutor最多 4 个 worker 并发,文件按001.jpg002.png的序号命名(保持传入顺序),最终输出{downloaded, files[], failed[]},其中每个文件记录urlpathsize_kb
  • 扩展名推断guess_extension,L47-L67):依次依据Content-Type、URL 后缀、文件魔数(magic bytes,如 PNG/ GIF/ WebP/ BMP/ JPEG)判断;
  • 安全护栏download_image首先用is_naver_url校验 URL 必须属于.naver.com/.naver.net/.pstatic.net域(见 _naver_http.py 的 is_naver_url),并用realpath校验输出路径不能逃逸目标目录(防路径穿越),请求头还带上了Referer: https://m.blog.naver.com/

八、推荐工作流与跨源验证

instruction.md 给出了一条完整的研究流水线:

  1. naver_search.py搜索,先查看前 3~5 条结果概览;
  2. 挑出相关度高的文章,用naver_read.py读取正文;
  3. 按需用naver_download_images.py保存图片;
  4. 与 WebSearch(Google)结果交叉验证,提升信息可信度。

这套流程的本质是"先摘要后精读、多信源交叉"的调研范式,Agent 按此执行即可避免盲目抓取整页结果。

九、响应策略与完成标准

Response policy(输出给用户时的约束)

  • 搜索结果与正文要摘要化后传达给用户,而非原文倾倒;
  • 必须附上博客出处(URL、作者);
  • 单个会话内避免过量请求(数十次以上);
  • 下载图片后要告知用户本地保存路径。

Done when(判定任务完成的标准)

  • 搜索结果能正常输出 JSON;
  • 博客正文文本成功提取;
  • 所需图片成功保存到本地;
  • 出处(来源)明确告知用户。

十、注意事项与限制(Notes)

文档末尾明确列出了三条运维级提醒,这是实际使用中必须接受的前提:

  1. IP 风控:脚本直接请求 Naver 搜索引擎,大量/自动化使用存在 IP 被封锁的可能,因此本技能被设计为小批量、非商业的轻量调研用途;
  2. HTML 易变:Naver 的页面结构可能随时调整,解析失败时需查看报错信息并更新脚本。这一点在源码中也有呼应——naver_search.py首页解析失败会打警告、naver_read.py找不到正文区域会输出warning字段;
  3. iframe 问题的技术缘由:PC 版blog.naver.com采用 iframe 结构,正文在嵌套文档中,因此统一改用移动版m.blog.naver.com直接提取。

另外,根目录 SKILL.md 及 references/ 下的法律声明文件(含韩国大法院判例与成文法依据)要求:自动收集公开信息必须限于个人、非组织用途,不得用于系统化/批量爬取、构建数据库、绕过访问控制或妨碍第三方业务。这与文档"当不要用时"的约束完全一致。

十一、质量保障:单元测试覆盖

仓库根目录的 scripts/test_naver_blog_search.py 为本技能提供了针对性测试,可佐证其核心逻辑的稳定性:

  • RequestBuilderTest:验证搜索参数构造——ssc锁定博客标签、首页用sm=tab_jum翻页切换为sm=tab_pgesim/date分别映射到不同的nso值;
  • ParseSearchResultsHiddenLabelTest:验证"새 창 열림"可访问性标签从标题/摘要中被正确剥离,且不会误伤正文中原本就含该词组的合法文本;
  • SearchWorkflowTest:mock 掉网络层,验证count=20时按 15 条一页翻页、URL 去重、跨页间隔sleep(0.5)以及date排序参数的透传。

测试直接通过importlib从 naver-blog-research/scripts/naver_search.py 加载模块进行单测,不依赖网络,证明了解析与分页逻辑可离线验证——如果你要二次开发这个技能,这套测试模式可以直接复用。

结语

naver-blog-research 是一个"小而完整"的调研技能样板:它用纯标准库解决了韩语博客搜索、正文提取、图片下载三个实际问题,并通过移动版 URL 转换、CDN 域名白名单、路径穿越防护、限速去重和明确的使用边界,把"轻量合规调研"落到了工程实处。结合本仓库中 4 个脚本源码与根目录测试用例,你可以直接掌握其请求构造、解析回退策略与并发下载的全部细节,并在此基础上按需扩展。

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询