博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用puppeteer爬取网站,抓出404无效链接
阅读量:7235 次
发布时间:2019-06-29

本文共 4216 字,大约阅读时间需要 14 分钟。

检查网页无效链接

前言

自动化技术可以帮助我们做自动化测试,同样也可以帮助我们完成别的事情,比如今天我们要做的检查网站404无效链接。

原理

实现这样的功能,大致分为以下步骤: 1.打开官网首页,获取页面上所有的链接。 2.添加规则对这些链接过滤,把外链去掉。 3.遍历访问这些链接,打开打开其中的每一个链接,检查是否为404,如果是距离下来。 4.重复执行1,2,3。直到把整个网站所有的链接都遍历完。

准备

  • CukeTest  一款可以专业的编辑自动化脚本的工具。
  • puppeteer 一个非常流行自动化库。

实现

CukeTest中新建一个项目。

删掉features目录。新建一个demo.js文件。

安装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);//获取所有的linkconst 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复制代码

获取更多相关知识,欢迎关注公众号

转载地址:http://etlfm.baihongyu.com/

你可能感兴趣的文章
C#编程总结(十)字符转码
查看>>
linux gcc头文件搜索路径
查看>>
对线程的理解
查看>>
更改linux swappiness 提高物理内存使用率
查看>>
J-Link GDB Server Command
查看>>
如何用.NET生成二维码?
查看>>
C++一个简单的手柄类模板
查看>>
The Water Problem(排序)
查看>>
atitit.无线上网卡 无法搜索WiFi 解决无线路由器信号不能被连接
查看>>
C#进阶系列——DDD领域驱动设计初探(三):仓储Repository(下)
查看>>
android 电容屏(三):驱动调试之驱动程序分析篇
查看>>
数字签名时间戳服务器的原理 !
查看>>
C++ Split string into vector<string> by space
查看>>
JavaScript学习——内置属性
查看>>
Oracle Profile 使用详解--zhuanzai
查看>>
Hadoop-1.1.2、HBase-0.94.7完全分布式集群结构
查看>>
TP-Link wr703N 使用华为HiLink系列上网卡的设置【转】
查看>>
士兵杀敌(四)(树状数组+线段树)
查看>>
Linux 高可用(HA)集群基本概念2
查看>>
Struts+Spring+Hibernate整合入门详解
查看>>