使用puppeteer爬取网站并抓出404无效链接


Posted in Javascript onDecember 20, 2018

检查网页无效链接

前言

自动化技术可以帮助我们做自动化测试,同样也可以帮助我们完成别的事情,比如今天我们要做的检查网站404无效链接。

原理

使用puppeteer爬取网站并抓出404无效链接

实现这样的功能,大致分为以下步骤: 1.打开官网首页,获取页面上所有的链接。 2.添加规则对这些链接过滤,把外链去掉。 3.遍历访问这些链接,打开打开其中的每一个链接,检查是否为404,如果是距离下来。 4.重复执行1,2,3。直到把整个网站所有的链接都遍历完。

准备

CukeTest 一款可以专业的编辑自动化脚本的工具。cuketest.com/

puppeteer 一个非常流行自动化库。https://github.com/GoogleChrome/puppeteer

实现

CukeTest中新建一个项目。

使用puppeteer爬取网站并抓出404无效链接

删掉features目录。新建一个demo.js文件。

使用puppeteer爬取网站并抓出404无效链接

安装puppeteer

npm install puppeteer --save

主要方法讲解

pupputeer内置监听事件,可以很快拿到每个请求的响应结果。

puppeteer可以创建Chromium实例。创建方式如下:

let puppeteer = require('puppeteer'); 
browser = await puppeteer.launch({ headless: true });
page = await browser.newPage();
await browser.close();

puppeteer 提供事件监听,可以监听到每个页面的响应状态,为每个请求添加响应事件,如果响应状态码为404,记录到文件中。

page.on('response',(res)=>{
 // console.log("res.url", res.url(), res.status())
 let url = res.url();
 if(res.status()==404){
  linktoFile(url, brokenlinkFile);
 }else{
  if(isvaildUrl(url)){
   linktoFile(url,validUrlFilePath);
  }
  
 } 
})

puppeteer抓取页面上所有的链接

await page.goto(url);
//获取所有的link
const hrefs = await page.evaluate(
 () => Array.from(document.body.querySelectorAll('a[href]'), ({ href }) => href)
);

将链接记录到文件或者从文件读取链接的方法

let filetoLinks = function (filepath) {
 if (!fs.existsSync(filepath)) {
  fs.writeFileSync(filepath);
 }
 let data = fs.readFileSync(filepath, 'utf-8')
 let links = data.trim().split('\n');
 return links;
}

let linktoFile = function (link, filepath) {
 let foundLinks = filetoLinks(filepath);
 if (!foundLinks.includes(link)) {
  fs.appendFileSync(filepath, link + '\n');
 }
}

最终代码

let puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');


const host = 'http://www.xxxx.cn/'; // 被测网站
const visitedFile = 'visitedUrl.txt'; //浏览过的页面
const visitedFilePath = path.join(__dirname, visitedFile);
const brokenlinkFile = 'brokenLink.txt'; //404链接
const brokenlinkFilePath = path.join(__dirname, brokenlinkFile);

const validUrlFile = 'validUrlFile.txt'; //可用的链接
const validUrlFilePath = path.join(__dirname,validUrlFile);

let browser;
let page;

function isvaildUrl(url){
 return url.startsWith(host) && !url.includes('/#');
}

async function run() {
 browser = await puppeteer.launch({ headless: true });

 page = await browser.newPage();
 page.on('response',(res)=>{
  // console.log("res.url", res.url(), res.status())
  let url = res.url();
  let currenturl = page.url()
  if(res.status()==404){
   linktoFile(currenturl+"=="+url, brokenlinkFilePath);
  }else{
   if(isvaildUrl(url)){
    linktoFile(url,validUrlFilePath);
   }
   
  } 
 })

 await visitPage(browser,page, host);

 await browser.close();

}

async function visitPage(browser,page, url) {
 // if (!isvaildUrl(url)) return;
 await page.goto(url);
 //获取所有的link
 const hrefs = await page.evaluate(
  () => Array.from(document.body.querySelectorAll('a[href]'), ({ href }) => href)
 );

 for (const href of hrefs) {
  //数据清洗
  if (isvaildUrl(href) && href !== host) {
   
   //符合条件的link
   // linktoFile(href, visitedFilePath);
   let res = await page.goto(href);
   
   if (res && res.status() == 404) {
    linktoFile(href, brokenlinkFilePath);
   } else {
    let visitedlinks = filetoLinks(visitedFilePath);
    if(!visitedlinks.includes(href)){
     linktoFile(href, visitedFilePath);
     await visitPage(browser,page,href);
     
    }
    
   }

   let links = filetoLinks(visitedFilePath);
   if (!links.includes(href)) {
    await visitPage(browser,page, href);
   }
  }
 }
}

let filetoLinks = function (filepath) {
 if (!fs.existsSync(filepath)) {
  fs.writeFileSync(filepath);
 }
 let data = fs.readFileSync(filepath, 'utf-8')
 let links = data.trim().split('\n');
 return links;
}

let linktoFile = function (link, filepath) {
 let foundLinks = filetoLinks(filepath);
 if (!foundLinks.includes(link)) {
  fs.appendFileSync(filepath, link + '\n');
 }
}

run();

运行

点击 【运行】按钮即可运行。 同样,在CukeTest中也支持命令行执行,执行命令为

cuke --runjs demo.js

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 屏蔽鼠标键盘的几段代码
Jan 02 Javascript
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
Dec 25 Javascript
JQuery自定义事件的应用 JQuery最佳实践
Aug 01 Javascript
JS实现表格数据各种搜索功能的方法
Mar 03 Javascript
js实现模拟银行卡账号输入显示效果
Nov 18 Javascript
js多个物体运动功能实例分析
Dec 20 Javascript
JS中如何实现点击a标签返回页面顶部的问题
Jan 19 Javascript
Angular 4依赖注入学习教程之简介(一)
Jun 04 Javascript
tsconfig.json配置详解
May 17 Javascript
Javascript三种字符串连接方式及性能比较
May 28 Javascript
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 Vue.js
浅谈JS的原型和原型链
Jun 04 Javascript
详解如何使用node.js的开发框架express创建一个web应用
Dec 20 #Javascript
js canvas实现橡皮擦效果
Dec 20 #Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
Dec 20 #Javascript
Cocos2d实现刮刮卡效果
Dec 20 #Javascript
浅谈Fetch 数据交互方式
Dec 20 #Javascript
cocos2dx+lua实现橡皮擦功能
Dec 20 #Javascript
element-ui table span-method(行合并)的实现代码
Dec 20 #Javascript
You might like
php foreach正序倒序输出示例代码
2014/07/01 PHP
如何使用php脚本给html中引用的js和css路径打上版本号
2015/11/18 PHP
php使用正则验证中文
2016/04/06 PHP
php通过header发送自定义数据方法
2018/01/18 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
jQuery 使用手册(五)
2009/09/23 Javascript
JQuery入门——移除绑定事件unbind方法概述及应用
2013/02/05 Javascript
Jquery时间验证和转换工具小例子
2013/07/01 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
javascript学习笔记(六)数据类型和JSON格式
2014/10/08 Javascript
cookie的secure属性详解
2015/04/08 Javascript
js验证框架之RealyEasy验证详解
2016/06/08 Javascript
常用jQuery选择器汇总
2017/02/02 Javascript
js中url对象化管理分析
2017/12/29 Javascript
详解VUE2.X过滤器的使用方法
2018/01/11 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
[00:52]黑暗之门更新 新英雄孽主驾临DOTA2
2016/08/24 DOTA
精确查找PHP WEBSHELL木马的方法(1)
2011/04/12 Python
python中去空格函数的用法
2014/08/21 Python
详解Python3中yield生成器的用法
2015/08/20 Python
简单讲解Python中的字符串与字符串的输入输出
2016/03/13 Python
PyQt5每天必学之带有标签的复选框
2018/04/19 Python
对python程序内存泄漏调试的记录
2018/06/11 Python
Django自定义模板过滤器和标签的实现方法
2019/08/21 Python
基于Python解密仿射密码
2019/10/21 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
2020/01/03 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
HTML5触摸事件实现移动端简易进度条的实现方法
2018/05/04 HTML / CSS
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
机械设计专业应届生求职信
2013/11/21 职场文书
求职简历推荐信范文
2013/12/02 职场文书
标准单位租车协议书
2014/09/23 职场文书
2015小学语文教师个人工作总结
2015/05/20 职场文书
党性修养心得体会2016
2016/01/21 职场文书