使用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 相关文章推荐
通过 Dom 方法提高 innerHTML 性能
Mar 26 Javascript
用tip解决Ext列宽度不够的问题
Dec 13 Javascript
浅析showModalDialog数据缓存问题(用禁止浏览器缓存解决)
Jul 09 Javascript
Javascript中的匿名函数与封装介绍
Mar 15 Javascript
JavaScript实现数组随机排序的方法
Jun 26 Javascript
Node.js下自定义错误类型详解
Oct 17 Javascript
支持移动端原生js轮播图
Feb 16 Javascript
JavaScript之map reduce_动力节点Java学院整理
Jun 29 Javascript
JavaScript之生成器_动力节点Java学院整理
Jun 30 Javascript
微信小程序实现简单跑马灯效果
May 26 Javascript
node爬取新型冠状病毒的疫情实时动态
Feb 06 Javascript
安装多版本Vue-CLI的实现方法
Mar 24 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 strrpos()与strripos()函数
2013/08/31 PHP
php旋转图片90度的方法
2013/11/07 PHP
Javascript 日期处理之时区问题
2009/10/08 Javascript
Prototype的Class.create函数解析
2011/09/22 Javascript
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
JS截取字符串常用方法整理及使用示例
2013/10/18 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
Javascript 按位与赋值运算符 (&=)使用介绍
2014/02/04 Javascript
JS使用oumousemove和oumouseout动态改变图片显示的方法
2015/03/31 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
2015/08/21 Javascript
详解Node.Js如何处理post数据
2016/09/19 Javascript
jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法
2016/10/14 Javascript
ES6概念 Symbol.keyFor()方法
2016/12/25 Javascript
js 实现省市区三级联动菜单效果
2017/02/20 Javascript
vue引入swiper插件的使用实例
2017/07/19 Javascript
详解React项目中碰到的IE问题
2019/03/14 Javascript
微信小程序云开发之数据库操作
2019/05/18 Javascript
JavaScript实现字符串与HTML格式相互转换
2020/03/17 Javascript
[54:17]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第二场 1月10日
2021/03/11 DOTA
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
Django中的ajax请求
2018/10/19 Python
Python 继承,重写,super()调用父类方法操作示例
2019/09/29 Python
python库skimage给灰度图像染色的方法示例
2020/04/27 Python
python数据类型强制转换实例详解
2020/06/22 Python
python按照list中字典的某key去重的示例代码
2020/10/13 Python
python excel多行合并的方法
2020/12/09 Python
美国折扣地毯销售网站:Rugs.com
2020/03/27 全球购物
大学生志愿者感言
2014/01/15 职场文书
银行纠风工作实施方案
2014/06/08 职场文书
励志演讲稿300字
2014/08/21 职场文书
秋季校运会广播稿100字
2014/09/18 职场文书
贫困生证明范文
2015/06/16 职场文书
感恩老师主题班会
2015/08/12 职场文书
会计继续教育培训心得体会
2016/01/19 职场文书
pandas求平均数和中位数的方法实例
2021/08/04 Python
详解JAVA的控制语句
2021/11/11 Java/Android