搜尋蜘蛛是按字节流讀取頁面的,狀態碼返回 200,並不等于内容被完整送出。如果连接在中途断開、压缩流没有正常結束,或者後端在超时後提前吐出半截 HTML,蜘蛛收到的就是一個“半成品”頁面:头部正常、正文缺失、頁脚的内鏈入口整体不见。這類問题不會在狀態碼統計里暴露,只會慢慢体現在 URL 發現變少、已收錄頁面内容長期不更新上。
截断的常见表現
- 同一 URL 多次抓取,日誌里的响應字节數忽大忽小,最大最小值差距明顯
- 頁面正文只到某個栏目就結束,頁脚導航、分頁、相關阅讀等入口整体消失
- 抓取耗时普遍贴近某個整數(如 30s、60s),像是被超时切断
- 返回体是空模板或“加载中”占位,狀態碼却仍是 200
- 蜘蛛抓取频次下降,新頁面迟迟等不到首次抓取
先確認是不是真的被截断
不要只看狀態碼。在服務器訪問日誌里补充记錄响應字节數和上游耗时,按 URL 分组對比:抓一份正常样本的字节數作為基线,再挑几個字节數偏低的 URL 用命令行复現,分別带和不带压缩請求头各取一次,比較實际寫入的字节數、响應头中声明的長度與實际長度是否一致。
如果带压缩时明顯偏短、不带压缩时正常,問题基本落在压缩层或传輸层,而不是模板本身。
常见的几類成因
压缩與传輸层不一致
响應头声明了長度但實际寫入不足、分块传輸缺少結束标记、压缩流被提前關閉,都會让客戶端認為响應到此為止。CDN、反向代理與應用三层同时開啟压缩时更容易出現這種情况。建议只在一层做压缩,並確認長度声明與實际内容一致。
後端超时後返回半截内容
模板渲染到一半、循环取數中断、流式輸出被上游掐断,都可能产出“前半段正常、後半段缺失”的 HTML。這類响應狀態碼常常還是 200,比 5xx 更难發現。較稳妥的做法是:渲染失敗时明确返回 5xx,或輸出一個结构完整的兜底頁面,而不是把残缺内容直接送出去。
代理與时序配置過紧
讀取超时、缓冲關閉、连接空闲回收等參數設定過短,會让服務端在内容寫完之前断開。观察被截断的 URL 是否集中在慢查询、大列表或依赖外部接口的頁面上,如果是,優先压缩這几類頁面的耗时,而不是一律放宽全局超时。
限流與连接重置
並發限制或防爬規則触發时,连接可能在寫入部分响應後被重置,日誌里常表現為同一 IP 段集中出現偏短的响應。核對限流阈值與蜘蛛抓取节奏是否冲突,必要时把已知搜尋蜘蛛的抓取與其他流量分開處理。
建议的排查顺序
- 补齐日誌字段:响應字节數、上游耗时、是否命中缓存。
- 按 URL 抽样,對比字节數基线與異常样本。
- 用带压缩與不带压缩两種方式复現,定位是压缩层還是應用层。
- 查看被截断頁面的共性:資料量、外部依赖、模板复杂度。
- 检查代理超时、缓冲與压缩配置,只保留一层压缩。
- 修复後持續观察字节數分布與抓取回訪频率,確認趋势稳定。
判断抓取是否健康,除了看狀態碼,還要看每一次响應是否完整交付。字节數是最容易被忽略、也最容易建立基线的一個指标。
修复後的观察重点
- 响應字节數集中在基线附近,異常样本占比下降
- 被截断頁面尾部的内鏈重新出現在抓取日誌中
- 慢頁面耗时下降,抓取不再卡在超时邊界
- 新提交的 URL 首次抓取時間趋于稳定
截断問题往往不是單点故障,而是超时、压缩、限流、模板兜底几處設定叠加的结果。按入口到後端逐层核對,先把“内容是否完整送達”這件事做扎實,URL 發現與内鏈传递才有意义。