死链检查脚本如何写?从零到一构建高效链接监控工具
📑 目录导读
- 什么是死链?为什么需要检查?
- 死链检查脚本的核心原理
- 五种主流脚本方案对比(Python/Shell/Node.js/Go/在线工具)
- 手把手教你写一个Python死链检查脚本(完整代码+注释)
- 脚本优化技巧:并发、超时、日志、SEO友好
- 常见问题与解决方案(问答环节)
- 实战部署建议:从命令行到定时任务
什么是死链?为什么需要检查?
死链(Broken Link) 指用户点击后无法正常访问的链接,常见状态码包括:

- 404 Not Found(页面已删除)
- 500 Internal Server Error(服务器故障)
- 403 Forbidden(权限不足)
- DNS解析失败(域名失效)
为什么必须检查死链?
- 用户体验:死链导致跳出率升高,用户流失。
- SEO影响:Google明确将死链视为低质量信号,排名下降。
- 爬虫资源浪费:搜索引擎爬虫反复访问死链,浪费抓取配额。
- 品牌形象:频繁死链让用户觉得网站维护不善。
根据Ahrefs 2024年SEO报告,平均每10个页面中就有1个存在至少一条死链,定期检查是维护「站点健康」的基础动作。
死链检查脚本的核心原理
无论用哪种语言,死链检查脚本都遵循三步逻辑:
输入URL列表 → 发送HTTP请求 → 分析响应状态码
关键参数设置:
- 超时时间:建议3~5秒,防止某个链接卡死整个脚本。
- 重定向跟随:默认不应跟随(status_code会变成200),需要记录原始URL的最终状态。
- 并发数:单线程太慢,建议用线程池或异步,但不要超过20并发以免被目标服务器封IP。
- User-Agent:伪装成Chrome或Googlebot,避免被反爬。
五种主流脚本方案对比
| 语言/工具 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Python + requests | 语法简单,生态丰富,支持并发 | 速度中等 | 中小型网站(<10万链接) |
| Shell + curl | 无需安装,极轻量 | 并发难处理,功能简陋 | 快速测试少量链接 |
| Node.js + axios | 异步IO效率高,适合超大批量 | 回调地狱,调试稍复杂 | 大型网站(百万级) |
| Go + net/http | 编译后单文件,执行极快 | 开发门槛稍高 | 需要打包分发的场景 |
| 在线工具(如Dr.Link Check) | 无需写代码 | 限制链接数,隐私风险 | 临时检查 |
推荐组合:日常使用Python脚本,量级过大时用Node.js或Go。
手把手教你写一个Python死链检查脚本
完整代码 (Python 3.8+)
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
import csv
import time
from urllib.parse import urlparse
# ============ 配置区域 ============
URL_FILE = "urls.txt" # 每行一个URL的文本文件
OUTPUT_CSV = "broken_links.csv" # 输出报告
THREADS = 10 # 并发数
TIMEOUT = 5 # 单个请求超时(秒)
BROKEN_CODES = [404, 403, 500, 502, 503] # 视为死链的状态码
# =================================
def is_broken_link(url):
"""检查单个链接是否死链,返回 (url, status, error)"""
try:
# 构造请求头,伪装成Chrome
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
# 不自动跟随重定向,获取原始状态码
resp = requests.get(url, headers=headers, timeout=TIMEOUT, allow_redirects=False)
status = resp.status_code
# 判断是否死链
if status in BROKEN_CODES:
error = f"HTTP {status}"
elif status >= 400:
error = f"HTTP {status} (其他客户端错误)"
else:
error = None # 正常链接
return (url, status, error)
except requests.exceptions.Timeout:
return (url, 999, "超时")
except requests.exceptions.ConnectionError:
return (url, 998, "连接失败")
except Exception as e:
return (url, 997, str(e))
def main():
# 1. 读取URL列表
with open(URL_FILE, 'r', encoding='utf-8') as f:
urls = [line.strip() for line in f if line.strip() and not line.startswith('#')]
print(f"共加载 {len(urls)} 个链接,开始检查...")
start_time = time.time()
broken_links = []
# 2. 并发检查
with ThreadPoolExecutor(max_workers=THREADS) as executor:
futures = {executor.submit(is_broken_link, url): url for url in urls}
for i, future in enumerate(as_completed(futures), 1):
url, status, error = future.result()
# 进度显示
if i % 50 == 0:
print(f"进度: {i}/{len(urls)}")
if error: # 死链
broken_links.append((url, status, error))
print(f"❌ 发现死链: {url} -> {error}")
# 3. 输出报告
with open(OUTPUT_CSV, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerow(['URL', '状态码', '错误原因'])
writer.writerows(broken_links)
elapsed = time.time() - start_time
print(f"\n✅ 检查完成!耗时 {elapsed:.2f} 秒")
print(f"共发现 {len(broken_links)} 个死链,报告已保存至: {OUTPUT_CSV}")
if __name__ == "__main__":
main()
使用步骤
- 安装依赖:
pip install requests - 准备
urls.txt文件,每行一个完整URL - 运行
python check_links.py - 查看输出文件
broken_links.csv
脚本优化技巧
🚀 性能优化
- 使用Session对象复用连接:将
requests.Session()用在每个线程中,减少TCP握手。 - 限制并发数:建议10~20,太高会被目标服务器封禁IP。
- 分批检测:超过5000个链接时,分文件执行,避免内存溢出。
📄 日志优化
- 添加
logging模块,记录每次检测的完整日志,便于回溯。 - 输出CSV报告时,同时输出HTML报告(用表格+状态标记),更直观。
🛡️ SEO友好
- 检测内部链接 vs 外部链接:外部链接死链仅记录,内部链接需要高亮。
- 生成SiteMap友好格式:输出死链列表后,建议同时生成一个
error_pages.txt,可提交给Google Search Console。 - 重定向检查:301/302状态码不应视为死链,但需要记录,避免大量重定向影响SEO。
🔄 集成到工作流
- Linux定时任务:
crontab -e添加每周末凌晨4点执行脚本。 - GitHub Actions:自动化每周检查,结果邮件通知。
- 对接Slack/钉钉:发现死链即发送告警。
常见问题与解决方案(问答环节)
Q1:被目标网站封IP怎么办?
- 添加随机延时
time.sleep(random.uniform(1, 3)) - 使用代理池,每次请求切换IP
- 设置
User-Agent轮换池
Q2:如何检测JavaScript渲染后的链接?
- 静态请求无法触发JS,需用Selenium或Playwright,但速度慢,建议先做静态检测,再对重要页面做浏览器渲染检测。
Q3:检查过程中报SSL证书错误?
- 添加参数
verify=False,但建议升级requests或指定证书路径。
Q4:超过10万链接如何快速检查?
- 改用Node.js异步方案,或使用Golang,同时分域名检测,避免单IP压力。
- 考虑使用CDN(如Cloudflare Workers)做分布式检查。
Q5:脚本跑完后发现误报(如重定向链接被标记)?
- 确保
allow_redirects=False,单独判断301/302状态码。 - 自定义
BROKEN_CODES列表,排除5xx临时错误(如503)。
实战部署建议:从命令行到定时任务
最小部署方案(5分钟搞定)
- 在服务器上创建脚本文件
check_links.py - 安装Python和requests
- 准备URL列表
urls.txt - 测试运行:
python check_links.py - 添加crontab:
0 4 * * 0 /usr/bin/python3 /home/user/check_links.py
进阶方案(适合技术团队)
使用配置文件 config.yaml,把URL列表、并发数、超时时间、告警方式分离,方便多站点管理。
sites:
- name: blog.example.com
url_file: urls_blog.txt
threads: 5
alert_email: seo@example.com
- name: shop.example.cn
url_file: urls_shop.txt
threads: 10
webhook: http://slack-webhook...
集成到CI/CD:在每次部署后自动检查新页面的链接,从源头避免死链上线。
写好一个死链检查脚本并不复杂,核心是“发送请求 → 判断状态码 → 记录结果”,但高效的脚本需要兼顾并发策略、超时控制、日志输出和SEO意图,本文提供的Python脚本可直接用于中小型网站,并给出了扩展方向,定期检查死链不是“一次性的活儿”,把它变成自动化工作流的一部分,才能真正守护用户体验和SEO排名。