Nodejs 批量检测 Excel 中url链接是否可访问

最近领导给我一个Excel表格,让我检查下其中的 Url 是否有效。作为一个开发人员,我内心是拒绝的,一个一个点击测试,估计手抽筋也测试不完。我想,人类的进步,源于使用工具,那我就写个程序跑一下吧,然后我去喝杯茶。

思路

  1. 读取 Excel 中数据
  2. 检测 url 是否有效
  3. 把数据写入 Excel
  4. 检查核对下数据

Excel 格式示例

序号分类名称网址状态
1A类某某网http://www.xxx.com/未检测
2A类某某网http://www.xxx.com/未检测
3A类某某网http://www.xxx.com/xxx未检测

撸起袖子,动手干吧

根据思路, 整理下代码吧
新建 index.js

const urlIsSuccess = require('./urlIsSuccess')
const { readSheets, getSheet, sheetsBuffer, writeFile } = require('./xlsx')

const entryfilePath = `${ __dirname }/test.xlsx`     // 输入的 Excel 文件
const outFilePath = `${ __dirname }/out_test.xlsx`   // 输出的 Excel 文件
const sheetIndex = 0;   // Excel 的 Sheet 索引
const urlColIndex = 3   // Excel 中 网址 所在的列索引
const statusColIndex = 4  // Excel 中 状态 所在的列索引

let sheets = readSheets(entryfilePath)   // 读取 Excel 中数据
const sheet = getSheet(sheets, sheetIndex)  // 读取 Excel 中 Sheet 数据

const isUrl = url => {
    if (!url) return false
    return /\s*http(s)?:\/\/.+/.test(url)
}

// 循环sheet表中的行数据
// 返回一个Promise数组, 用于 Promise.all 使用
let promises = sheet.map(rows => {
    const url = rows[ urlColIndex ]
    if (isUrl(url)) {
        return urlIsSuccess(url).then(res => {
             // 返回检测的状态码, 写入状态格
            rows[ statusColIndex ] = res
            return Promise.resolve(rows)
        })
    }
    return Promise.resolve(rows)
})

Promise.all(promises).then((res) => {
    sheets[ sheetIndex ].data = res;
    const buffer = sheetsBuffer(sheets)
    writeFile(buffer, outFilePath)
}).catch(err => {
    console.log('err=', err)
})

操作 Excel 中数据

需要安装node-xlsx npm install node-xlsx --save
新建 xlsx.js

const fs = require("fs")
const xlsx = require('node-xlsx').default;
// 读取Excel表全部数据
const readSheets = (filePath) => {
    if (!filePath) return []
    return xlsx.parse(filePath)
}
// 读取Excel表中Sheet数据
const getSheet = (sheets, nameOrIndex) => {
    if (nameOrIndex === undefined) return sheets

    if (typeof nameOrIndex === 'string') {
        return sheets.find(sheet => nameOrIndex === sheet.name)?.data
    }

    if (typeof nameOrIndex === 'number') {
        return sheets[ nameOrIndex ]?.data
    }

    throw new Error(`nameOrIndex 不合法: ${ nameOrIndex }`)
}

const sheetsBuffer = (sheets) => {
    if (!sheets) {
        throw new Error(`sheets 参数是必填项`)
    }
    return xlsx.build(sheets)
};

// 写入文件,需要提前手动创建
const writeFile = (buffer, outFilePath) => {
    fs.writeFile(outFilePath, buffer, function (err) {
        if (err) {
            console.log("写入失败: " + err);
            return;
        }

        console.log("写入完成");
    });
}

module.exports = {
    readSheets,
    getSheet,
    sheetsBuffer,
    writeFile
}

检测 url 是否有效

使用 nodejs 的 child_process.exec(),调用 命令行curl命令, 根据返回的错误状态码或者HTTP状态码,判断 URL 是否有效
新建 urlIsSuccess.js

const child_process = require("child_process");

const urlIsSuccess = (url) => {
    if (!url) {
        return Promise.resolve('')
    }
    // 微信内置浏览器 "Mozilla/5.0 AppleWebKit/600 Mobile MicroMessenger/6.0"
    const userAgent = '-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"'
    const curl = `curl -I ${ userAgent }  ${ url }`

    return new Promise((resolve, reject) => {

        child_process.exec(curl, function (err, stdout, stderr) {
            console.log(url, '完成')
            if (err) {
                resolve(err.code || '失败')
                return
            }

            let status = stdout.split('\n')
            if (status.length) {
                let code = status[ 0 ].match(/\s(\d{3})\s/)
                if (code && code[ 1 ]) {
                    status = +code[ 1 ]
                }
            }
            if (!status) {
                status = stdout;
            }

            resolve(status || '成功')
        });
    })

}

module.exports = urlIsSuccess;


注意

有部分网站,做了人机检测, 需要对请求头等进行配置,否则通过curl访问会失败

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了 义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值