使用puppeteer之全网页截图-修订版 超、凢脫俗 2021-09-20 03:02 481阅读 0赞 [https://blog.csdn.net/ASAS1314/article/details/84847770][https_blog.csdn.net_ASAS1314_article_details_84847770] 内容简介: 接上一篇的内容之前,简单介绍一下puppeteer环境的快速搭建; 修订版目的; 修订版具体实现,代码展示。 1、puppeteer运行环境快速搭建 以下是个人从无到有的搭建过程,linux、windows系统搭建,大同小异: 1.1、首先是node.js的安装 1.1.1、官网下载安装包,node-v11.3.0-linux-x64.tar.xz 1.1.2、复制至/usr/local下 1.1.3、解压:tar -xvf node-v11.3.0-linux-x64.tar.xz 1.1.4、配置/etc/profile export NODEJS\_HOME=/usr/local/nodejs export PATH=$NODEJS\_HOME/bin:$PATH 1.1.5、执行source /etc/profile,查看node.js安装情况:node -v,查看npm安装情况:npm -v \[master@master nodejs\]$ node -v v11.3.0 \[master@master nodejs\]$ npm -v 6.4.1 1.2、安装puppeteer 如果是项目,则cd至项目路径下,如果是执行js文件,则安装在与js文件的同级目录下,因为实际场景中会有项目运行,以及一些单独运行的小项目存在,根据不同场景自行选择。 1.2.1、安装cnpm,直接通过npm安装puppeteer,容易失败,使用阿里淘宝的源 npm install -g cnpm --registry=https://registry.npm.taobao.org \-g参数,说明是全局安装。 1.2.2、查看cnpm版本 [master@master nodejs]$ cnpm -v cnpm@6.0.0 (/usr/local/nodejs/lib/node_modules/cnpm/lib/parse_argv.js) npm@6.4.1 (/usr/local/nodejs/lib/node_modules/cnpm/node_modules/npm/lib/npm.js) node@11.3.0 (/usr/local/nodejs/bin/node) npminstall@3.16.0 (/usr/local/nodejs/lib/node_modules/cnpm/node_modules/npminstall/lib/index.js) prefix=/usr/local/nodejs linux x64 3.10.0-693.el7.x86_64 registry=https://registry.npm.taobao.org 1.2.3、安装puppeteer cnpm install puppeteer 等待完成,到这里环境的基本搭建就完成了。如果是有node.js的其他安装包,先运行npm install,再运行puppeteer,因为经常更新环境,发现单独对puppeteer进行升级,会导致node\_modules下的软链接文件夹被删除。 2、修订版目的 理由:第一个版本太丑陋了。 3、修订版实现 其实已经写完很久了,一直疏于整理。主要针对第一个版本中的滚屏进行修改,看过第一版知道,其实现滚屏的方式是修改html页面中scrollTop的值。 document.scrollingElement.scrollTop = scrollTop + scrollStep; 实际上可以使用window对象的相关函数。 上代码: // puppeteer测试DEMO var puppeteer = require('puppeteer'); (async() => { let timeoutMillSeconds = 10000; let waitUntilStr = 'domcontentloaded'; let headlessFlag = false; const system_warn = 1002; // 系统提示/告警 let args = [ '--no-sandbox', '--disable-infobars ', // don't show information bar '--window-size=1920,1080', // resize window view port size '--lang=zh-CN', '--disable-dev-shm-usage' ]; const browser = await puppeteer.launch({ defaultViewport: {width: 1920, height: 1080}, ignoreHTTPSErrors: true, headless:headlessFlag, args: args }); const page = await browser.newPage(); let request_url = 'https://blog.csdn.net/ASAS1314/article/details/81633423'; await page.goto(request_url, {timeout:timeoutMillSeconds, waitUntil: waitUntilStr}).catch(err => { }); let height_limit = false; let scroll_times = 0; let mValues = {'scrollEnable': true, 'height_limit': height_limit, 'times': 10}; let result_map = new Map(); try { await page.waitFor(5000); while (mValues.scrollEnable) { mValues = await page.evaluate((max_height_px, page_screentshot_height_limit, height_limit, result_map, system_warn, request_url, scroll_times ) => { let times = 1; let scrollEnable = true; if (undefined !== document.body && null != document.body) { window.scrollBy(0, window.innerHeight); times = parseInt(document.body.clientHeight / 1080); // 超出图片的限制高度, 生成PDF if (document.body.clientHeight > page_screentshot_height_limit) { height_limit = true; } // 超出网页的限制高度, 不再滚动 if (document.body.clientHeight > max_height_px && scroll_times > 40) { result_map['resultCode'] = system_warn; result_map['warning'] = '网页加载高度过长, 易造成数据获取失败。'; scrollEnable = false; } } else { scrollEnable = false; } times = times + 1; return { 'scrollEnable': scrollEnable, 'height_limit': height_limit, 'times': times, 'title':document.title }; }, 60000, 60000, height_limit, result_map, system_warn, request_url, scroll_times); // 等待随机时间 let randomMillSecond = randomNum(600, 2000); await sleep(randomMillSecond); scroll_times++; console.log(request_url + ' 需要滚动 : ' + mValues.times + '次 , 滚动第[' + scroll_times + ']次'); if (scroll_times > mValues.times) { console.log(request_url + ' 结束'); mValues.scrollEnable = false; } } console.log(mValues); await page.screenshot({path: 'example.png', fullPage: true}); } catch (e) { console.log(e); console.log('执行异常'); } finally { await browser.close(); } })(); // 随机数 function randomNum(minNum, maxNum) { switch (arguments.length) { case 1: return parseInt(Math.random() * minNum + 1, 10); case 2: return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); default: return 0; } } // 延时函数 function sleep(delay) { return new Promise((resolve, reject) => { setTimeout(() => { try { resolve(1) } catch (e) { reject(0) } }, delay) }) } 真实线上的代码比这个来的复杂得多,这是被我阉割后的简易版本。 优化点:滚动优化,实时计算滚动次数,因为现在的页面大部分是动态加载。 上结果:没截全 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3o2OTE4Mzc4Nw_size_16_color_FFFFFF_t_70][] [https_blog.csdn.net_ASAS1314_article_details_84847770]: https://blog.csdn.net/ASAS1314/article/details/84847770 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3o2OTE4Mzc4Nw_size_16_color_FFFFFF_t_70]: /images/20210527/f0326b46aede4ea6a5ad54722fc50619.png
还没有评论,来说两句吧...