檢查網頁無效連結
前言
自動化技術可以幫助我們做自動化測試,同樣也可以幫助我們完成別的事情,比如今天我們要做的檢查網站404無效連結。
原理
實現這樣的功能,大致分為以下步驟: 1.開啟官網首頁,獲取頁面上所有的連結。 2.新增規則對這些連結過濾,把外鏈去掉。 3.遍歷訪問這些連結,開啟開啟其中的每一個連結,檢查是否為404,如果是距離下來。 4.重複執行1,2,3。直到把整個網站所有的連結都遍歷完。
準備
- CukeTest 一款可以專業的編輯自動化指令碼的工具。cuketest.com/
- puppeteer 一個非常流行自動化庫。github.com/GoogleChrom…
實現
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);
//獲取所有的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
複製程式碼
獲取更多相關知識,歡迎關注公眾號