使用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 相关文章推荐
cookie的复制与使用记住用户名实现代码
Nov 04 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
jQuery实现垂直半透明手风琴特效代码分享
Aug 21 Javascript
javascript弹性运动效果简单实现方法
Jan 08 Javascript
jquery实现表单获取短信验证码代码
Mar 13 Javascript
Angular CLI 安装和使用教程
Sep 13 Javascript
对于input 框限定输入值为浮点型的js代码
Sep 25 Javascript
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
Nov 28 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
Sep 30 Javascript
从源码里了解vue中的nextTick的使用
Nov 22 Javascript
微信小程序之onLaunch与onload异步问题详解
Mar 28 Javascript
vue项目实现分页效果
Mar 24 Vue.js
详解如何使用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代码
2008/09/10 PHP
手把手教你打印出PDF(关于fpdf的简单应用)
2013/06/25 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
2014/08/25 PHP
javascript 避免闭包引发的问题
2009/03/17 Javascript
js打开windows上的可执行文件示例
2014/05/27 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
2014/09/25 Javascript
JS+CSS实现另类带提示效果的竖向导航菜单
2015/10/15 Javascript
javascript+HTML5自定义元素播放焦点图动画
2016/02/21 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
BootStrap tab选项卡使用小结
2020/08/09 Javascript
js使用Replace结合正则替换重复出现的字符串功能示例
2016/12/27 Javascript
node.js实现回调的方法示例
2017/03/01 Javascript
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
详解nodeJS之二进制buffer对象
2017/06/03 NodeJs
Vue.js实现输入框绑定的实例代码
2017/08/24 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
详解如何写出一个利于扩展的vue路由配置
2019/05/16 Javascript
浅谈ECMAScript 中的Array类型
2019/06/10 Javascript
es6中new.target的作用和使用场景简单示例分析
2020/03/14 Javascript
[01:20]DOTA2更新全新英雄 天涯墨客现已加入游戏
2018/08/25 DOTA
Python编程实现删除VC临时文件及Debug目录的方法
2017/03/22 Python
Python Logging 日志记录入门学习
2018/06/02 Python
python实现密码强度校验
2020/03/18 Python
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
奢华时尚的创新平台:Baltini
2020/10/03 全球购物
群众路线党课主持词
2014/04/01 职场文书
后勤管理员岗位职责
2014/08/27 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
践行党的群众路线心得体会
2014/11/05 职场文书
2014年保险业务员工作总结
2014/12/23 职场文书
催款函范本大全
2015/06/24 职场文书
教师培训简讯
2015/07/20 职场文书
小公司融资,商业计划书的8切记
2019/07/15 职场文书
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
2021/04/01 PHP
python异步的ASGI与Fast Api实现
2021/07/16 Python