运维群里最怕看到的判断批量一句话是“网站打不开了”。更怕的网页是,手上有四十多个域名,状态客户挨个问过来,检查你根本不知道哪个真挂了、工具哪个只是判断批量自己网络抽风。上个月帮朋友处理他那个小电商站群,网页五十几个页面,状态我手动点开浏览器一个个看状态码,检查点到第二十个的工具时候手已经麻了。后来写了个Python脚本,判断批量三分钟跑完,网页红色标注的状态失效链接列得清清楚楚。
判断网页状态,检查核心就是工具那个HTTP状态码。200代表一切正常,服务器把内容正常吐出来了。301、302是跳转,不算坏,但得看跳去哪儿了。404是页面不存在,500是服务器内部错误,403是权限被拒。批量检查要做的就是把这些码抓回来,按颜色分类。
很多人用curl循环,简单粗暴:
for url in $(cat urls.txt); do code=$(curl -o /dev/null -s -w "%{ http_code}" "$url") echo "$code $url" done 这法子能用,但慢。串行执行,一个卡住后面全等。五十个链接跑下来,遇上两三个超时的,十分钟就没了。换成并发,用Python的concurrent.futures或者Go的goroutine,速度能压到十几秒。我自己的脚本用的是aiohttp,异步发请求,超时设5秒,超过就标记为“TIMEOUT”,不跟它耗。
这里有个细节:有些网站会屏蔽脚本请求。你直接发requests.get,对方返回403,但浏览器打开是正常的。原因是User-Agent暴露了。加一行headers={ 'User-Agent': 'Mozilla/5.0 ...'},大部分就放行了。还有更狠的,检查Referer或者用Cloudflare的人机验证,那种批量工具也束手无策,只能手动过。
另一个容易踩的坑是重定向。requests默认跟着跳转走,最后返回的是落地页的状态码。如果你想知道原始链接是不是301,得设allow_redirects=False。我一般会记录两个值:原始状态码和最终状态码。原始301、最终200,说明跳转链路健康;原始301、最终404,那就是跳进死胡同了。
写这种工具,输出格式比技术实现更重要。纯文本列表没人愿意看。我习惯输出成HTML表格,200绿色、301蓝色、404橙色、500红色,一眼扫过去就知道该修哪个。再加一列响应时间,超过3秒的标黄——状态码正常但慢得像蜗牛的页面,用户体验也好不到哪去。
有个做SEO的朋友拿这个工具跑竞品网站,专门找404页面。他说一个网站如果有大量404,要么是改版没做重定向,要么是内容下架没清理,都是能拿来分析的情报。这角度我倒没想过,工具本身不复杂,看你怎么用。
代码写到最后,其实最花时间的是异常处理。DNS解析失败、SSL证书过期、连接被重置,这些都不返回HTTP状态码,但都是实打实的故障。我的做法是给每个异常类型分配一个伪状态码:DNS_FAIL、SSL_ERROR、CONN_RESET,跟正常状态码一起输出。这样一份报告出来,该修的、该查的、该忽略的,分得明明白白。
工具这东西,够用就行。别追求什么图形界面、定时任务、邮件告警,那是另一个量级的工程。一个check.py加一个urls.txt,命令行跑完出HTML报告,扔给运营自己看。省下来的时间,够你喝两杯咖啡了。