背景
因為近期在專案中出現過頁面中靜態資源丟失的情況。其中圖片居多,因為頁面較多,往往都是客戶發現丟失了圖片,才開始定位缺失的圖片資源,再進行補救。因此,基於
puppeteer
寫了一個簡單的頁面抓取圖片資源進行排查的node.js
指令碼。
優勢
-
可配置
通過配置排查的頁面的URL
地址,根據順序逐個排查,把錯誤的靜態資源詳情持久化。 -
使用靈活
本地可以獨立配置使用,無需服務端支援。
不足
-
被動型
人為啟動指令碼進行排查,也可以新增定時任務,按時間段進行排查。不能主動監聽頁面缺失檔案,不能第一時間找到錯誤靜態資源。
概念&流程
目前專案中的圖片資源主要是兩種使用方式:
-
html
的img
標籤 -
css
檔案的background-image
針對兩種使用方式,採取不同的策略:
-
img
標籤使用
以單一頁面為單位,爬取HTML並通過puppeteer
的page.evaluate()
方法匹配出頁面上所有的<img>
標籤中的src
屬性寫成陣列。通過node
的https
模組迴圈對抓取的陣列內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
出裡面所有的圖片。
通過node
的https
模組迴圈對陣列內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
等欄位。
模擬的測試檔案
一個html
頁面,html中引用多張圖片,需要有不少於2個的錯誤img
資源,引用多份css
檔案,需要有一個合併的css
檔案。並且每個合併的檔案需要有多個錯誤img
資源。
TODOS
- 通過配置檔案對增加的頁面地址統一排查。
- 對新的CDN路徑分析,移植到新的CDN環境上。
- 增加一些更加友好的使用體驗。