蜘蛛池知识

蜘蛛池入口頁的字符编碼:乱碼、声明冲突和蜘蛛實际讀到的内容

入口頁在浏览器里看着正常,不代表抓取端讀到的也是正常文本。编碼声明冲突、BOM 头和拼接過程中的多次轉碼,都會让頁面在蜘蛛眼里變成乱碼或空白。本文說明這些情况怎么产生、會導致什么後果,並给出一份按顺序排查的自检清單和可以固定下来的编碼习惯。

蜘蛛池知识

蜘蛛池入口頁的字符编碼:乱碼、声明冲突和蜘蛛實际讀到的内容

编碼問题為什么值得單獨拎出来说

蜘蛛抓到一個入口頁,拿到的是字节流,它要按某個規則把字节還原成字符,才能判断這頁在讲什么、标题是什么、有没有和目标頁相關的词。如果還原過程出错,頁面在蜘蛛眼里可能就是一堆乱碼或者空白。人眼在浏览器里看到的是正常的,是因為浏览器做了容错和猜测;抓取端不一定有同样的容错策略,也不一定會像浏览器那样反复试。

所以编碼不是排版细节,它直接影响頁面能不能被讀懂。

三種最常见的情况

1. 响應头和 meta 声明不一致

服務器返回的 Content-Type 里寫了 charset=gbk,頁面 meta 里却寫着 utf-8,两邊打架。這时候按哪個走取决于具体實現,可能是响應头優先,也可能是先讀一段字节再猜。结果就是同一批入口頁里,一部分正常、一部分乱碼,排查时很費劲。

建议统一:要么全站 UTF-8,要么全站 GBK,別混用。响應头、meta、文件本身儲存的编碼三者保持一致。

2. BOM 头

UTF-8 文件如果带了 BOM,會在文件最前面多出三個不可见字节。有些拼装頁面或輸出的程序也可能重复寫入 BOM,導致頁面開头出現几個奇怪字符,甚至把 doctype 顶到後面去。解析时偶尔會因此判错文档類型,或者把 head 部分讀乱。

3. 資料库和模板各寫各的

入口頁内容通常是從資料库、接口、模板里拼出来的。資料库连接设成一種编碼,模板文件是另一種,程序輸出时又轉了一次,三次轉換里错一次,頁面就會出問号、方块或者连續的問号串。這種問题往往只在包含中文的字段上出現,英文數字正常,所以更隐蔽。

乱碼之後會發生什么

  • 關鍵詞對不上。頁面上本来有的词變成乱碼,抓取端做主题判断时就少了一個依據。
  • 模板重复度看起来更高。正文都成了乱碼,剩下的可区分内容就只剩结构和标簽,頁面之間的差异被压得更小。
  • 标题和锚文本失效。标题乱碼會影响蜘蛛對這條連結指向哪里的判断。
  • 正文被判為無意义。有些處理流程會直接丢弃看不懂的文本块,頁面等于空壳。

這几点叠加起来,表現就是抓取意愿下降、回訪變少,而你在浏览器里看頁面却是正常的。這正是编碼問题麻烦的地方。

一份自检顺序

  1. 用 curl 或抓取工具直接取一次原始响應,先看响應头里的 charset。
  2. 把返回的字节按响應头声明的编碼解碼,看中文是否正常。
  3. 再按 UTF-8 解一次,對比两次结果,判断哪邊是對的。
  4. 检查文件是否带 BOM,尤其是用某些編輯器另存過的模板。
  5. 检查資料库连接、表、字段、模板文件的编碼設定是否一致。
  6. 抽查一批頁面而不是只看首頁,因為拼接路径不同的頁面表現可能不一样。

顺带说一句首屏

编碼正确之後,還要看首屏有没有有效内容。有些入口頁把大段模板導航、广告位或者空容器放在最前面,真正的内容要往下滚動才出現。抓取端拿到的 HTML 顺序和你看到的视觉顺序可能不同,如果正文被塞在一堆重复结构後面,判断頁面的有效信息就會更費劲。把關键的一句說明放在靠前位置,比堆装饰性模块更實际。

几個可以固定下来的习惯

  • 新入口頁统一 UTF-8,包括資料库、模板、响應头。
  • 上线前用脚本抽查原始响應,別只靠浏览器目测。
  • 批量生成流程里加一步编碼校驗,發現異常就拦下来。
  • 把编碼检查寫進日常巡检,和狀態碼、响應時間一起看。
编碼問题不會让頁面立刻消失,但它會让頁面在蜘蛛眼里變得模糊。模糊的頁面,得到的關注通常也少。