使用puppeteer爬蟲,檢查頁面靜態資源丟失

271626514發表於2019-02-16

背景

因為近期在專案中出現過頁面中靜態資源丟失的情況。其中圖片居多,因為頁面較多,往往都是客戶發現丟失了圖片,才開始定位缺失的圖片資源,再進行補救。因此,基於puppeteer寫了一個簡單的頁面抓取圖片資源進行排查的node.js指令碼。

優勢

  • 可配置
    通過配置排查的頁面的URL地址,根據順序逐個排查,把錯誤的靜態資源詳情持久化。
  • 使用靈活
    本地可以獨立配置使用,無需服務端支援。

不足

  • 被動型
    人為啟動指令碼進行排查,也可以新增定時任務,按時間段進行排查。不能主動監聽頁面缺失檔案,不能第一時間找到錯誤靜態資源。

概念&流程

目前專案中的圖片資源主要是兩種使用方式:

  • htmlimg標籤
  • css檔案的background-image

針對兩種使用方式,採取不同的策略:

  • img標籤使用

以單一頁面為單位,爬取HTML並通過puppeteerpage.evaluate()方法匹配出頁面上所有的<img>標籤中的src屬性寫成陣列。通過nodehttps模組迴圈對抓取的陣列內src進行訪問,如果有404,即代表著該靜態資源缺失,並把該資源的詳情寫入錯誤圖片的log日誌中log/*/ERRIMGFILE.js

  • css檔案使用

同樣以單一頁面為單位,爬取HTML抓取頁面的<link>標籤的rel屬性寫成陣列。(需要注意的是,一般來說頁面上的css引用都是通過<link>標籤的,但是反之則未必,比如頁面的一些icon也是使用link標籤引入的,因此我們需要對抓取的link標籤進行篩選)。根據目前專案的特點,css檔案有經過伺服器壓縮合並請求的版本,因此需要對這類的樣式檔案進行拆分使之成為可以外部可以訪問的單一css檔案。這裡我以汽車之家車商城主會場引用的伺服器合併後的css為例分析:

//x.autoimg.cn/com/co.ashx?path=|mall|2015|pc|js|swiper|swiper-3.4.2.min-6af34.css,|mall|topic|2017|9|hbyy|pc|css|game-8a737.css,|mall|2015|pc|css|index-all-d010e.css

分析得出,我們需要的單一的css檔案應該是如下這種形式的集合

//x.autoimg.cn/mall/2015/pc/js/swiper/swiper-3.4.2.min-6af34.css
//x.autoimg.cn/mall/2015/pc/css/index-all-d010e.css
//x.autoimg.cn/mall/topic/2017/9/hbyy/pc/css/game-8a737.css

那麼根據目標,我們先將合併的css後半部分中的co.ashx?path=進行分解,得到3個css檔案的字串,該字串通過,拼接,並且在內部是用|分割的路徑,因此經過一些拆分和替換,再拼上前面的domain就得到了一組可用來訪問的css路徑集合。

當然,頁面上除了這樣經過伺服器處理的css外,還有一些單獨引用的,我們也一併把這些路徑新增到上面處理過後的css路徑集合中。

現在全部的css路徑我們拿到了,開始逐個檔案的排查裡面用到的圖片。通過puppeteer提供的方法page.goto(`css檔案地址`)開啟一個新的頁面,分析頁面上的結構,抓取到該css的全部內容,通過正則匹配///.+?.(jpg|png|gif)/g出裡面所有的圖片。

通過nodehttps模組迴圈對陣列內src進行訪問,如果有404,即代表著該靜態資源缺失,並把該資源的詳情寫入錯誤圖片的log日誌中log/*/ERRCSSIMGFILE.js

目錄&檔案的作用

  • log/*/*.js存放指令碼生成的log檔案。
檔名 介紹
LOGFILE.js 存放指令碼執行的操作。包含有:頁面共計引用的img標籤,頁面引用的css檔案,全部css檔案中引用的圖片,以及每個css檔案引用的圖片路徑。
ERRIMGFILE.js 存放錯誤的html<img>標籤引入資源。包含的欄位有:錯誤資源條數;錯誤資源詳情的列表。
ERRCSSIMGFILE.js 存放錯誤的css檔案引用的圖片資源。包含的欄位有:錯誤資源條數;錯誤資源詳情的列表。
  • config.json新增的排查任務頁面。
欄位 介紹
taskAlias 任務別名:可輸入中文,作為快速檢視log日誌的索引。
taskName 任務名稱:不可輸入中文。
taskUrl 任務地址:指令碼執行的路徑,爬蟲開始由該地址爬行抓取內容。
  • config.js指令碼的配置檔案。
欄位 介紹
cdnPath 靜態資源存放的域名。
cssPath css檔案存放的域名,帶有協議。
cssFilter 合併的css引數,主要用於匹配合並後的css
imgReg 匹配圖片資源規則。

針對CDN遷移,需要同步修改cdnPath,cssPath等欄位。

模擬的測試檔案

基於tms搭建的測試地址

一個html頁面,html中引用多張圖片,需要有不少於2個的錯誤img資源,引用多份css檔案,需要有一個合併的css檔案。並且每個合併的檔案需要有多個錯誤img資源。

TODOS

  • 通過配置檔案對增加的頁面地址統一排查。
  • 對新的CDN路徑分析,移植到新的CDN環境上。
  • 增加一些更加友好的使用體驗。

參考資料

puppeteer中文文件

原始碼

GitHub:puppeteer-demo

相關文章