使用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 面向对象思想 附源码
Jul 07 Javascript
javascript call方法使用说明
Jan 11 Javascript
js定时器怎么写?就是在特定时间执行某段程序
Oct 11 Javascript
jQuery DOM删除节点操作指南
Mar 03 Javascript
javascript搜索框效果实现方法
May 14 Javascript
JS敏感词过滤代码
Dec 23 Javascript
浅谈js中function的参数默认值
Feb 20 Javascript
easy ui datagrid 从编辑框中获取值的方法
Feb 22 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
Dec 25 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
Mar 17 Javascript
详解vuex状态管理模式
Nov 01 Javascript
Vue.directive 实现元素scroll逻辑复用
Nov 29 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摘要生成函数(无乱码)
2012/02/04 PHP
php实现的简单检验登陆类
2015/06/18 PHP
PHP导入导出Excel代码
2015/07/07 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
2019/07/03 PHP
Jquery下的26个实用小技巧(jQuery tips, tricks & solutions)
2010/03/01 Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
2013/06/05 Javascript
jQuery页面加载初始化常用的三种方法
2014/06/04 Javascript
jQuery图片特效插件Revealing实现拉伸放大
2015/04/22 Javascript
基于JQuery实现仿网易邮箱全屏动感滚动插件fullPage
2015/09/20 Javascript
JavaScript中SetInterval与setTimeout的用法详解
2015/11/10 Javascript
BootStrap 图标icon符号图标glyphicons不正常显示的快速解决办法
2016/12/08 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
JavaScript仿支付宝6位数字密码输入框
2016/12/29 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
JavaScript实现简单精致的图片左右无缝滚动效果
2017/03/16 Javascript
使用canvas及js简单生成验证码方法
2017/04/02 Javascript
js移动端图片压缩上传功能
2020/08/18 Javascript
react redux入门示例
2018/04/19 Javascript
详解javascript中的babel到底是什么
2018/06/21 Javascript
小程序实现多列选择器
2019/02/15 Javascript
javascript异步处理与Jquery deferred对象用法总结
2019/06/04 jQuery
javascript 模块依赖管理的本质深入详解
2020/04/30 Javascript
python中assert用法实例分析
2015/04/30 Python
python可视化实现KNN算法
2019/10/16 Python
python如何绘制疫情图
2020/09/16 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
财务方面个人工作的自我评价
2013/12/28 职场文书
工伤事故赔偿协议书范文
2014/09/24 职场文书
关于对大人不礼貌的检讨书
2014/09/29 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
公司员工宿舍管理制度
2015/08/03 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书
微信小程序scroll-view不能左右滑动问题的解决方法
2021/07/09 Javascript
Win11任务栏太宽了怎么办?一招解决Win11任务栏太宽问题
2021/11/21 数码科技
什么是Python装饰器?如何定义和使用?
2022/04/11 Python
CentOS7安装MySQL8的超级详细教程(无坑!)
2022/06/10 Servers