使用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 相关文章推荐
33个优秀的 jQuery 图片展示插件分享
Mar 14 Javascript
5分钟理解JavaScript中this用法分享
Nov 09 Javascript
js中的caller和callee属性介绍和例子
Jun 07 Javascript
javascript实现控制的多级下拉菜单
Jul 05 Javascript
简单谈谈javascript Date类型
Sep 06 Javascript
详解angular中如何监控dom渲染完毕
Jan 03 Javascript
JavaScript中arguments和this对象用法分析
Aug 08 Javascript
jquery实现的简单轮播图功能【适合新手】
Aug 17 jQuery
JS跨域请求的问题解析
Dec 03 Javascript
微信小程序websocket实现即时聊天功能
May 21 Javascript
Layui选项卡制作历史浏览记录的方法
Sep 28 Javascript
vuejs实现下拉框菜单选择
Oct 23 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/10/04 PHP
详谈php中 strtr 和 str_replace 的效率问题
2017/05/14 PHP
因str_replace导致的注入问题总结
2019/08/08 PHP
Aster vs KG BO3 第三场2.18
2021/03/10 DOTA
JavaScript 中的replace方法说明
2007/04/13 Javascript
javascript动态加载二
2012/08/22 Javascript
JS+CSS实现Li列表隔行换色效果的方法
2015/02/16 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
jquery专业的导航菜单特效代码分享
2015/08/29 Javascript
浅谈jquery点击label触发2次的问题
2016/06/12 Javascript
JS图片左右无缝隙滚动的实现(兼容IE,Firefox 遵循W3C标准)
2016/09/23 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(放大缩小)
2016/12/02 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
2017/03/15 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
AngularJS中下拉框的高级用法示例
2017/10/11 Javascript
[03:59]5分钟带你了解什么是DOTA2(第二期)
2017/02/07 DOTA
pymongo给mongodb创建索引的简单实现方法
2015/05/06 Python
正确理解python中的关键字“with”与上下文管理器
2017/04/21 Python
Python学习小技巧之利用字典的默认行为
2017/05/20 Python
python 矩阵增加一行或一列的实例
2018/04/04 Python
django2.0扩展用户字段示例
2019/02/13 Python
对pyqt5多线程正确的开启姿势详解
2019/06/14 Python
python获取点击的坐标画图形的方法
2019/07/09 Python
HTML5文档结构标签
2017/04/21 HTML / CSS
介绍一下Make? 为什么使用make
2016/07/31 面试题
《春天来了》教学反思
2014/04/07 职场文书
班组长安全工作职责
2014/07/15 职场文书
银行职员工作失误检讨书
2014/10/14 职场文书
给老婆的检讨书
2015/01/27 职场文书
校本研修个人总结
2015/02/28 职场文书
保研推荐信格式
2015/03/25 职场文书
孕妇病假条怎么写
2015/08/17 职场文书
2016年元旦寄语
2015/08/17 职场文书
环保建议书作文300字
2015/09/14 职场文书
Go语言空白表示符_的实例用法
2021/07/04 Golang
美国运营商 T-Mobile 以 117.83Mb/s 的速度排第一位
2022/04/21 数码科技