使用puppeteer之全網(wǎng)頁(yè)截圖-第一個(gè)版本

免責(zé)聲明:本人博客所有文章純屬學(xué)習(xí)之用,不涉及商業(yè)利益。不合適引用,自當(dāng)刪除!

先說(shuō)一些廢話

因?yàn)槭菧y(cè)試,沒(méi)有給出項(xiàng)目的具體搭建流程。

Puppeteer是谷歌官方出品的一個(gè)通過(guò)DevTools協(xié)議控制headless Chrome的Node庫(kù)。可以通過(guò)Puppeteer的提供的api直接控制Chrome模擬大部分用戶操作來(lái)進(jìn)行UI Test或者作為爬蟲(chóng)訪問(wèn)頁(yè)面來(lái)收集數(shù)據(jù)。所以開(kāi)發(fā)語(yǔ)言當(dāng)然也就是js啦。

Github項(xiàng)目地址:puppeteer

puppeteer API:puppeteer API,現(xiàn)在看的時(shí)候版本是1.7.0。

puppeteer的簡(jiǎn)單使用,大家可以參照官網(wǎng)上的demo,或者百度出來(lái)的文章,都會(huì)有相關(guān)的代碼,但是似乎puppeteer用的人相對(duì)較少,所以真實(shí)資料也少很多。能找到的文章就是那么幾篇。至于puppeteer的安裝就不累訴了,搜索一下,相信各位能找到,這里主要是針對(duì)使用puppeteer對(duì)訪問(wèn)網(wǎng)頁(yè)后,對(duì)全網(wǎng)頁(yè)進(jìn)行截圖(無(wú)對(duì)網(wǎng)頁(yè)重出現(xiàn)的特殊場(chǎng)景進(jìn)行處理,如:驗(yàn)證碼、登錄框等)。

以https://www.jd.com為例。注意點(diǎn):需要翻頁(yè),否則頁(yè)面加載不全,則截圖時(shí),展示不全。后續(xù)會(huì)有優(yōu)化版。

上代碼

無(wú)翻頁(yè)版本,寫到這里就簡(jiǎn)單的給出類似demo的例子:



// 導(dǎo)入包

const puppeteer =require('puppeteer');

(async () => {

// 啟動(dòng)Chromium

? ? const browser =await puppeteer.launch({ignoreHTTPSErrors:true, headless:false, args: ['--no-sandbox']});

? ? // 打開(kāi)新頁(yè)面

? ? const page =await browser.newPage();

? ? // 設(shè)置頁(yè)面分辨率

? ? await page.setViewport({width:1920, height:1080});

? ? let request_url ='https://www.jd.com';

? ? // 訪問(wèn)

? ? await page.goto(request_url, {waitUntil:'domcontentloaded'}).catch(err => console.log(err));

? ? await page.waitFor(1000);

? ? let title =await page.title();

? ? console.log(title);

? ? try {

// 截圖

? ? ? ? await page.screenshot({path:"jd.jpg", fullPage:true}).catch(err => {

console.log('截圖失敗');

? ? ? ? ? ? console.log(err);

? ? ? ? });

? ? ? ? await page.waitFor(5000);

? ? }catch (e) {

console.log('執(zhí)行異常');

? ? }finally {

await browser.close();

? ? }

})();



運(yùn)行結(jié)果截圖:


無(wú)翻頁(yè)版本

可以發(fā)現(xiàn),圖片缺失嚴(yán)重,不管你在代碼中等待多久,都是沒(méi)用的,需要對(duì)頁(yè)面進(jìn)行滾動(dòng),觸發(fā)頁(yè)面的滾動(dòng)事件。滾動(dòng)版本,這個(gè)版本可以實(shí)現(xiàn)滾動(dòng),但是覺(jué)得代碼寫的不好,而且對(duì)個(gè)別一些網(wǎng)站不兼容,所以才成為第一個(gè)版本:



const puppeteer =require('puppeteer');

(async () => {

// 啟動(dòng)Chromium

? ? const browser =await puppeteer.launch({ignoreHTTPSErrors:true, headless:false, args: ['--no-sandbox']});

? ? // 打開(kāi)新頁(yè)面

? ? const page =await browser.newPage();

? ? // 設(shè)置頁(yè)面分辨率

? ? await page.setViewport({width:1920, height:1080});

? ? let request_url ='https://www.jd.com';

? ? // 訪問(wèn)

? ? await page.goto(request_url, {waitUntil:'domcontentloaded'}).catch(err => console.log(err));

? ? await page.waitFor(1000);

? ? let title =await page.title();

? ? console.log(title);

? ? // 網(wǎng)頁(yè)加載最大高度

? ? const max_height_px =20000;

? ? // 滾動(dòng)高度

? ? let scrollStep =1080;

? ? let height_limit =false;

? ? let mValues = {'scrollEnable':true, 'height_limit': height_limit};

? ? while (mValues.scrollEnable) {

mValues =await page.evaluate((scrollStep, max_height_px, height_limit) => {

// 防止網(wǎng)頁(yè)沒(méi)有body時(shí),滾動(dòng)報(bào)錯(cuò)

? ? ? ? ? ? if (document.scrollingElement) {

let scrollTop = document.scrollingElement.scrollTop;

? ? ? ? ? ? ? ? document.scrollingElement.scrollTop = scrollTop + scrollStep;

? ? ? ? ? ? ? ? if (null != document.body && document.body.clientHeight > max_height_px) {

height_limit =true;

? ? ? ? ? ? ? ? }else if (document.scrollingElement.scrollTop + scrollStep > max_height_px) {

height_limit =true;

? ? ? ? ? ? ? ? }

let scrollEnableFlag =false;

? ? ? ? ? ? ? ? if (null != document.body) {

scrollEnableFlag = document.body.clientHeight > scrollTop +1081 && !height_limit;

? ? ? ? ? ? ? ? }else {

scrollEnableFlag = document.scrollingElement.scrollTop + scrollStep > scrollTop +1081 && !height_limit;

? ? ? ? ? ? ? ? }

return {

'scrollEnable': scrollEnableFlag,

? ? ? ? ? ? ? ? ? ? 'height_limit': height_limit,

? ? ? ? ? ? ? ? ? ? 'document_scrolling_Element_scrollTop': document.scrollingElement.scrollTop

? ? ? ? ? ? ? ? };

? ? ? ? ? ? }

}, scrollStep, max_height_px, height_limit);

? ? ? ? await sleep(800);

? ? }

try {

await page.screenshot({path:"jd.jpg", fullPage:true}).catch(err => {

console.log('截圖失敗');

? ? ? ? ? ? console.log(err);

? ? ? ? });

? ? ? ? await page.waitFor(5000);

? ? }catch (e) {

console.log('執(zhí)行異常');

? ? }finally {

await browser.close();

? ? }

})();

//延時(shí)函數(shù)

function sleep(delay) {

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

setTimeout(() => {

try {

resolve(1)

}catch (e) {

reject(0)

}

}, delay)

})

}


結(jié)果截圖:


不滿意的滾動(dòng)版本

可以看到,效果還是可以的,至于等待時(shí)間,需要根據(jù)你的網(wǎng)絡(luò)環(huán)境進(jìn)行延時(shí)。當(dāng)然,此版本只是為了大家學(xué)習(xí)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容