使用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 相关文章推荐
js window.event对象详尽解析
Feb 17 Javascript
JQuery操作iframe父页面与子页面的元素与方法(实例讲解)
Nov 20 Javascript
JavaScript删除指定子元素代码实例
Jan 13 Javascript
Node.js静态文件服务器改进版
Jan 10 Javascript
基于jquery实现轮播特效
Apr 22 Javascript
js添加千分位的实现代码(超简单)
Aug 01 Javascript
jQuery Ajax File Upload实例源码
Dec 12 Javascript
JavaScript函数节流的两种写法
Apr 07 Javascript
jquery replace方法去空格
May 08 jQuery
vue bootstrap小例子一枚
Jun 09 Javascript
Vue 父子组件数据传递的四种方式( inheritAttrs + $attrs + $listeners)
May 04 Javascript
微信小程序开发实现的IP地址查询功能示例
Mar 28 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
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
PIGCMS 如何关闭聊天机器人
2015/02/12 PHP
PHP实现阳历到农历转换的类实例
2015/03/07 PHP
php redis实现对200w用户的即时推送
2017/03/04 PHP
jQuery验证Checkbox是否选中的代码 推荐
2011/09/04 Javascript
Javascript无阻塞加载具体方式
2013/06/28 Javascript
jquery用data方法获取某个元素上的事件
2014/06/23 Javascript
javascript巧用eval函数组装表单输入项为json对象的方法
2015/11/25 Javascript
JavaScript中Textarea滚动条不能拖动的解决方法
2015/12/15 Javascript
实现JavaScript高性能的数据存储
2016/12/11 Javascript
JS实现获取来自百度,Google,soso,sogou关键词的方法
2016/12/21 Javascript
用file标签实现多图文件上传预览
2017/02/14 Javascript
canvas时钟效果
2017/02/16 Javascript
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
基于vue-resource jsonp跨域问题的解决方法
2018/02/03 Javascript
详解使用create-react-app添加css modules、sasss和antd
2018/07/31 Javascript
Vue实现开心消消乐游戏算法
2019/10/22 Javascript
在Python的Django框架下使用django-tagging的教程
2015/05/30 Python
如何使用python爬取csdn博客访问量
2016/02/14 Python
python实现抖音视频批量下载
2018/06/20 Python
python使用PIL模块获取图片像素点的方法
2019/01/08 Python
Django实现文件上传下载
2019/10/06 Python
python基于event实现线程间通信控制
2020/01/13 Python
Python3 实现爬取网站下所有URL方式
2020/01/16 Python
HTML5使用DOM进行自定义控制示例代码
2013/06/08 HTML / CSS
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
咖啡店的创业计划书,让你hold不住
2014/01/03 职场文书
承诺书的格式范文
2014/03/28 职场文书
小学生一分钟演讲稿
2014/08/26 职场文书
热情服务标语
2014/10/07 职场文书
廉政承诺书2015
2015/04/28 职场文书
大学副班长竞选稿
2015/11/21 职场文书
2016年社区服务活动总结
2016/04/06 职场文书
如何在Python中创建二叉树
2021/03/30 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
2021/06/05 Python