使用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 相关文章推荐
xml和web特殊字符
Apr 28 Javascript
jquery 插件学习(五)
Aug 06 Javascript
JavaScript—window对象使用示例
Dec 09 Javascript
动态读取JSON解析键值对的方法
Jun 03 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
Sep 28 Javascript
浅析JavaScript 调试方法和技巧
Oct 22 Javascript
json传值以及ajax接收详解
May 24 Javascript
JS实现页面跳转参数不丢失的方法
Nov 28 Javascript
JS实现动画兼容性的transition和transform实例分析
Dec 13 Javascript
Node.js+Express+MySql实现用户登录注册功能
Jul 10 Javascript
基于js中document.cookie全面解析
Sep 14 Javascript
20多个小事例带你重温ES10新特性(小结)
Sep 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
基于文本的访客签到簿
2006/10/09 PHP
PHP 读取文件内容代码(txt,js等)
2009/12/06 PHP
PHP实现的MongoDB数据库操作类分享
2014/05/12 PHP
利用switch语句进行多选一判断的实例代码
2016/11/14 PHP
Zend Framework入门教程之Zend_View组件用法示例
2016/12/09 PHP
JavaScript 面向对象之命名空间
2010/05/04 Javascript
jQuery中多个元素的Hover事件解决方案
2014/06/12 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
JavaScript模板引擎用法实例
2015/07/10 Javascript
JS获取月份最后天数、最大天数与某日周数的方法
2015/12/08 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
jquery实现input框获取焦点的简单实例
2017/01/26 Javascript
JavaScript中立即执行函数实例详解
2017/11/04 Javascript
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
2019/10/11 Javascript
使用Vue实现调用接口加载页面初始数据
2019/10/28 Javascript
vue3+typescript实现图片懒加载插件
2020/10/26 Javascript
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
Python 获取当前所在目录的方法详解
2017/08/02 Python
Python多线程扫描端口代码示例
2018/02/09 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
Pycharm及python安装详细教程(图解)
2020/07/31 Python
python openCV实现摄像头获取人脸图片
2020/08/20 Python
TheFork葡萄牙:欧洲领先的在线餐厅预订平台
2019/05/27 全球购物
菜篮子工程实施方案
2014/03/08 职场文书
2014婚礼司仪主持词
2014/03/14 职场文书
小学教师师德承诺书
2014/05/23 职场文书
消防安全标语
2014/06/07 职场文书
改作风抓落实促发展心得体会
2014/09/10 职场文书
群众路线领导干部个人对照检查材料(集锦)
2014/09/23 职场文书
公司股份转让协议书范本
2015/01/28 职场文书
关于CSS浮动与取消浮动的问题
2021/06/28 HTML / CSS
基于Python实现nc批量转tif格式
2022/08/14 Python