使用puppeteer爬虫,检查页面静态资源丢失

背景

因为近期在项目中出现过页面中静态资源丢失的情况。其中图片居多,因为页面较多,往往都是客户发现丢失了图片,才开始定位缺失的图片资源,再进行补救。因此,基于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静态资源存放的域名。
cssPathcss文件存放的域名,带有协议。
cssFilter合并的css参数,主要用于匹配合并后的css
imgReg匹配图片资源规则。
针对CDN迁移,需要同步修改cdnPath,cssPath等字段。

模拟的测试文件

基于tms搭建的测试地址

一个html页面,html中引用多张图片,需要有不少于2个的错误img资源,引用多份css文件,需要有一个合并的css文件。并且每个合并的文件需要有多个错误img资源。

TODOS

  • 通过配置文件对增加的页面地址统一排查。
  • 对新的CDN路径分析,移植到新的CDN环境上。
  • 增加一些更加友好的使用体验。

参考资料

puppeteer中文文档

源码

GitHub:puppeteer-demo

相关推荐