ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

remote-jobs 仓库链接失效治理实战:check-links.sh 与 fix-links.mjs 维护管线全解析

remote-jobs 仓库链接失效治理实战:check-links.sh 与 fix-links.mjs 维护管线全解析 数据集【免费下载链接】remote-jobsSource for remoteintech.company — a community-maintained directory of remote-friendly tech companies项目地址https://gitcode.com/GitHub_Trending/re/remote-jobs点击查看免费下载导读remote-in-tech 是一个社区维护的远程友好型科技公司目录其源码仓库 remote-jobs 中沉淀了 884 份公司档案 Markdown 文件累计承载约 2,200 条外链。随着时间推移公司域名过期、被收购改版、招聘页下架等现象必然导致链接腐烂link rot。本文以 scripts/README.md 为主线结合 scripts/check-links.sh 与 scripts/fix-links.mjs 的源码实现完整讲解这套扫描 → 分类 → 人工复核 → 安全修复的维护管线读完你将掌握全量外链扫描、10 类问题分级、浏览器 UA 二次核验、自动修复边界把控以及六周一次的例行维护工作流。一、为什么静态目录仓库需要专门的链接维护管线src/companies/下每个公司档案是一个带 YAML frontmatter 的 Markdown 文件其中website与careers_url两个字段是核心外链frontmatter 模板见 CONTRIBUTING.md--- title: Example Co slug: example-co website: https://example.com careers_url: https://example.com/careers region: worldwide remote_policy: fully-remote company_size: small technologies: - javascript - python ---这类内容靠社区 PR 持续增长CONTRIBUTING.md 中约 884 个公司档案、近 900 条website字段站点本身是构建期静态生成Eleventy没有运行时探活能力。因此维护者将链接健康度检查完全独立到构建流程之外做成按需运行的临时脚本ad-hoc scripts。关键设计原则在 scripts/README.md 中明确写出所有命令必须从仓库根目录运行而不是scripts/目录内部扫描与修复产生的四个中间产物——extracted-urls.txt、link-check-results.csv、link-fix-plan.md、link-fix-applied.log——全部落在仓库根目录且已在 .gitignore 中忽略第 65–70 行不会污染版本库。二、管线总览两个脚本、一条流水线src/companies/*.md │ (--refresh) 提取 frontmatter Markdown 正文中的 URL ▼ check-links.sh ──► extracted-urls.txt ──► 并发 curl 探活 ──► link-check-results.csv │ fix-links.mjs读取 CSV ├─ --reverify 二次核验可疑行 ├─ 分类OK / HTTPS_UPGRADE / ... ├─ --apply 应用安全修复 ├─ 输出 link-fix-plan.md人工评审计划 └─ 输出 link-fix-applied.log已应用变更日志两个脚本职责分离check-links.sh只负责探活并记录事实fix-links.mjs负责决策并执行变更。前者是纯 Bash curl后者是 Node.js 脚本仓库要求 Node.js ≥ 22见 package.json。三、第一阶段check-links.sh 全量外链扫描3.1 三种运行模式scripts/README.md 给出的三种调用方式与语义完全对应 scripts/check-links.sh 中的参数解析第 21–30 行./scripts/check-links.sh # 全量扫描约 2,200 条 URL耗时约 8 分钟 ./scripts/check-links.sh --quick # 只复查上次运行中非 OK的 URL ./scripts/check-links.sh --refresh # 先从公司档案重新提取 URL再做全量扫描--refresh或-r重新从src/companies/*.md提取 URL 列表覆盖extracted-urls.txt适合新增/删除公司后使用--quick或-q读取上一次的link-check-results.csv只保留其中no_change_needed不为 No 的行以及新出现的 URL 进行复查并自动把上次的 OK 行复制进新结果显著缩短迭代周期。两个标志可以组合如./scripts/check-links.sh --refresh --quick语义上为先提取新 URL 再只查非 OK 项。3.2 从公司档案中提取 URL--refresh 的提取逻辑提取逻辑位于 scripts/check-links.sh分两路并行frontmatter 字段用grep -E ^(website|careers_url):抓取每份档案的website与careers_url再用sed s/^[^:]*: *//剥掉键名前缀、tr -d 去掉引号Markdown 正文先用awk /^---$/,/^---$/{next}跳过 frontmatter 区域再以grep -oE https?://[^)\\] 正则抓取正文中所有链接。两路结果统一写为文件路径|URL格式竖线分隔最后sort -u去重并打印Found N URLs统计。所以扫描范围是档案全文frontmatter 正文而非仅website字段。3.3 并发请求、超时与 User-Agentscripts/check-links.sh 的check_url函数是核心探活实现其 curl 调用值得逐参数解读curl -L -s -o /dev/null -w %{http_code}|%{url_effective}|%{redirect_url}|%{num_redirects} \ --connect-timeout $TIMEOUT \ --max-time 30 \ -A Mozilla/5.0 (compatible; LinkChecker/1.0) \ $url-L跟随重定向直到最终页-w自定义输出格式返回四个字段HTTP 状态码、重定向后的最终 URLurl_effective、下一次重定向地址、重定向次数--connect-timeout 15脚本常量TIMEOUT15与--max-time 30双重超时兜底自定义 UALinkChecker/1.0标识爬虫身份——这个 UA 恰恰是后续误判 THROTTLED 的根源也是--reverify用浏览器 UA 换身份重查的原因状态码000表示 curl 层失败连接失败/超时会被统一改写为ERROR并保留原 URL。并发控制方面scripts/check-links.sh优先使用 GNUparallel带进度条--bar任务数MAX_PARALLEL20未安装时回退到 xargs 风格的手写并行——以后台执行check_url每满 20 个任务wait一次并打印进度。check_url通过export -f导出以便子进程调用每次结果写入独立临时文件最后合并保证并发写不冲突。3.4 CSV 输出格式与状态解释输出文件link-check-results.csv的列固定为source_file, original_url, resolved_url, status_code, explanation, no_change_needed即来源档案、原始 URL、重定向后最终 URL、HTTP 状态码、一句话解释、是否需要变更。explanation与no_change_needed的映射逻辑scripts/check-links.sh如下status_codeexplanationno_change_neededERRORcurl 失败Connection failed or timeoutYes200且 URL 与最终 URL 一致OKNo200但存在重定向num_redirects0Redirects to final URLYes301/302/303/307/308Redirect (not followed to completion)Yes404Not found (broken link)Yes403Forbidden (may be blocking bots)Review401UnauthorizedReview500/502/503/504Server errorReview其他HTTP codeReview扫描结束时脚本还会打印摘要统计Total checked、OK无需变更、Redirects、Broken404、Connection errors。四、第二阶段fix-links.mjs 分类与安全修复fix-links.mjs读取link-check-results.csv经过丢弃失效源文件行 → 二次核验 → 分类 → 规划/应用修复四个阶段。调用方式scripts/README.md 原文 源码参数解析node scripts/fix-links.mjs # 生成 link-fix-plan.md不修改任何档案 node scripts/fix-links.mjs --reverify # 先用浏览器 UA DNS 复核可疑行 node scripts/fix-links.mjs --apply # 生成计划 AND 应用安全修复实际参数解析在 scripts/fix-links.mjs--apply与--reverify两个标志不带任何标志时默认只生成计划README 中的--plan行为。4.1 十级分类体系核心表格scripts/README.md 中的分类表是整条管线的决策依据与 scripts/fix-links.mjs 的classify()/classifyRedirect()逐一对应分类含义是否自动应用OKURL 可用且无重定向否无需处理HTTPS_UPGRADEhttp→https且 host 与 path 完全一致是直接升级COSMETIC仅尾斜杠 /www/:443端口差异否现状可用CAREERS_DEAD招聘 URL 重定向到首页、登录页、错误页等是删除 careers_url 字段SAFE_REDIRECT同一可注册域registrable domain内有意义路径迁移部分仅纯路径迁移子类自动应用REBRAND可注册域已更换收购/品牌更替否需人工评审NOT_FOUND404否需人工评审PARKED最终 URL 落在域名停放服务商eco-mind 模式是删除整个档案DEAD_DNS主机名完全无法解析是删除整个档案THROTTLED403/429/999/连接失败疑似反爬拦截否先--reverifyUNKNOWN其他一切否4.2 内置启发式规则让机器看得懂互联网自动分类之所以可靠依赖 scripts/fix-links.mjs 中一系列精心设计的启发式规则PARKED 识别第 35–49 行内置了 11 个知名停放服务商域名如sedoparking.com、afternic.com、hugedomains.com、godaddy.com/domainsearch等并配合子域名正则^(ww\d|parking|park|expired)\.捕获劫持/错拼跳转的常见特征。判断优先级最高只要最终 URL 命中即判 PARKED。注册域判定第 120–130 行registrable()采用公开后缀近似法——取主机名最后两段并特判co.uk、co.jp、com.br、com.au等双段后缀足以区分github.com与www.github.com同一注册域以及foo.com与bar.com不同注册域。跟踪参数剥离第 203–211 行TRACKING_PARAMS正则覆盖utm_、gclid、fbclid、msclkid、mc_、_ga、_gl、sessionid、sid、ref等比较前后 URL 前先剔除这些参数避免仅多了追踪参数被误判为真实变更。Dead-end 与招聘页识别第 212–243 行DEAD_END_PATHS匹配/oops、/error、/404、/login、/contact等通用死胡同页isCareersPath()匹配路径中含career|job|hiring|join|work|apply|vagas|vacanc的招聘路径LOCALE_SEG_RE识别en-gb、pt-br、intl、locale等区域段——这些正是扫描地域不同导致的伪差异绝不自动固化进档案。重定向分类决策树第 276–353 行按优先级依次判断——http→https 同 host 同 pathHTTPS_UPGRADE仅 www/尾斜杠/端口差异COSMETIC落入 dead-end 页CAREERS_DEAD招聘路径→根路径或非招聘路径CAREERS_DEADWorkable/Lever/Greenhouse 等 ATS 域名跳回首页CAREERS_DEAD注册域变更REBRAND子域名变更、geo-block、新增 locale 段、根路径→具体路径均判为 SAFE_REDIRECT 但不自动应用只有同 host 的有意义路径迁移才标记autoApply: true。4.3 --reverify 二次核验浏览器 UA DNS 兜底为什么需要这一步README 给出了明确数字LinkChecker UA 会被部分站点反爬拦截--reverify可将 THROTTLED 误报率降低约 15%并能区分DNS 无法解析域名真死了与连接被拒真实限流。实现位于 scripts/fix-links.mjsreverify()用真实浏览器 UAChrome/121 完整 UA 字符串加全套 Sec-Fetch 头Sec-Fetch-Dest: document等重新请求20 秒超时AbortControllerfetch 失败时调用node:dns/promises的lookup()兜底判断——DNS 能解析说明是反爬/证书问题DNS 解析失败则标记dnsDead。执行时只对当前分类为 THROTTLED 或 NOT_FOUND 的行重查并发度 8结果会回写link-check-results.csvscripts/fix-links.mjs让后续--apply基于更可靠的数据决策。所以 README 建议的--reverify先于--apply是有代码依据的。4.4 --apply 的安全边界自动应用被严格限制在三类动作scripts/fix-links.mjsREADME 明确承诺了四条红线不改 Markdown 正文中的 URL除非该 URL 与正在改写的 frontmatter URL 完全一致text.replaceAll(u.from, u.to)全量替换保证正文与 frontmatter 同步不固化扫描地域性跳转如/→/en-gb/这类 locale 差异会被localeSegments/stripLocale识别并跳过不保留跟踪参数cleanFinalUrl()在写回前剥离所有 query 参数与 hash并归一化:443/:80端口噪声COSMETIC 类一律不写尾斜杠、www、端口差异现状即可用。4.5 三类自动动作与产物自动动作触发条件具体操作删除整个档案website字段落入 PARKED 或 DEAD_DNSunlink()删除src/companies/{slug}.md剥离 careers_url 字段careers_url 为 NOT_FOUND / CAREERS_DEAD / PARKED / DEAD_DNS且网站本体正常正则删除该行 frontmatter改写 URLwebsite/careers_url为 HTTPS_UPGRADE 或可自动应用的 SAFE_REDIRECT全文件替换为清洗后的最终 URL每次--apply都会生成link-fix-applied.log逐条记录REMOVED 文件 — 原因、removed careers_url (...)、website http→https: from → to等变更而无论是否 --apply脚本都会生成link-fix-plan.md内含分类摘要、可自动应用的改写表、删除候选表、REBRAND/收购对照表、NOT_FOUND 清单与 THROTTLED 提醒scripts/fix-links.mjs供人工评审使用。五、典型工作流六周一次的维护节奏scripts/README.md 给出的完整维护流程可直接照搬# 1. 每约 6 周或收到贡献者报告的死链时先重新提取 URL 并全量扫描 ./scripts/check-links.sh --refresh # 2. 二次核验 应用安全修复README 强烈建议二者连用 node scripts/fix-links.mjs --reverify --apply # 3. 审查变更 cat link-fix-applied.log git diff --stat # 4. 人工过一遍其余分类 $EDITOR link-fix-plan.md # REBRAND、NOT_FOUND、残留 THROTTLED 需要人工判断 # 5. 版本号、提交、PR六、源码级设计要点回顾事实与决策分离check-links.sh产出原始 CSV 事实fix-links.mjs依据规则决策任何一步出错都可单独重跑而不丢上下文宁可漏修不可误改autoApply: true只授予同 host 纯路径迁移这一最安全的子类REBRAND、NOT_FOUND、THROTTLED 一律进人工评审清单降误报三板斧跟踪参数剥离、locale 段识别、浏览器 UA DNS 兜底核验共同把机器误判降到可人工过目量级结果可审计link-fix-applied.log与link-fix-plan.md构成变更审计链路配合git diff即可复查每一次自动修改产物不入库四个中间文件全部在 .gitignore 中忽略维护流程不会污染仓库历史。如果希望在贡献前预先了解档案字段结构可阅读 CONTRIBUTING.mdfrontmatter 模板与合法取值若需理解构建期如何消费这些档案可查看 src/companies/companies.11tydata.js 与 eleventy.config.js。这套管线把约 2,200 条外链 × 每 6 周一次的重复劳动压缩为三条命令加一次人工评审正是大型社区目录保持数据新鲜度的关键基建。赞分享数据集【免费下载链接】remote-jobsSource for remoteintech.company — a community-maintained directory of remote-friendly tech companies项目地址https://gitcode.com/GitHub_Trending/re/remote-jobs点击查看免费下载相关推荐Backstage CLI 维护模块实战指南使用 repo fix 与 repo list-deprecations 管理仓库健康Backstage CLI 维护模块实战指南使用 repo fix 与 repo list deprecations 管理仓库健康 导读 本文聚焦 BacksUI组件前端stylelint 仓库维护实战Issue 管理流程、标签体系与规范全解析stylelint 仓库维护实战Issue 管理流程、标签体系与规范全解析 本指南基于 stylelint 官方维护文档 docs/maintainer g代码质量静态分析前端从 Balsamiq 档案解读 remote-jobs 仓库远程友好公司条目的数据结构、渲染与维护全流程从 Balsamiq 档案解读 remote jobs 仓库远程友好公司条目的数据结构、渲染与维护全流程 导读 本文以 remote jobsRemote数据集上一篇shadcn-svelte Field 上手指南原生语义打造可访问的响应式表单下一篇Doctrine Inflector 完全指南从单词变形到多语言规则定制的实用手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表