const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 转到要下载的网页并设置视口大小 await page.goto('http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=FDA38AB7D08A715C6B6D69DFDEABB2C0'); // 把 width/height 调整到适合 pdf 大小 await page.setViewport({width: 1920, height: 2000}); // 监听页面上的控制台输出 page.on('console', message => { const args = message.args(); console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()} ${args.length ? '\n' : ''}`); for (let i = 0; i < args.length; ++i) { console.log(` ${i}: ${args[i]}`); } }); console.log('wait for user stdin') await new Promise(resolve => process.stdin.once('data', resolve)); console.log('start scroll page...') // 模拟用户滚动页面 await page.evaluate(async () => { await new Promise(resolve => { let totalHeight = 0; let distance = 100; let timer = setInterval(() => { // #viewer const node = document.getElementById('viewer') let scrollHeight = node.scrollHeight; document.getElementById('viewerContainer').scrollBy(0, distance); totalHeight += distance; if (totalHeight >= scrollHeight) { clearInterval(timer); resolve(); } }, 100); }); }); console.log('scroll page finished') console.log('wait for network idle') // 等待所有资源加载完成 await page.waitForNetworkIdle({idleTime: 1000, timeout: 30 * 1000}); console.log('wait for network finished') console.log('start task') // 获取指定的 DOM 元素 const pages = await page.$$('.page'); let number = 1 for await (let element of pages) { // await page.evaluate((node) => node.scrollIntoView(), element) // 获取指定 DOM 元素在页面中的位置和尺寸 const boundingBox = await element.boundingBox(); console.log(page, boundingBox) // 截取指定区域的截图,并将截图保存到本地文件系统中 const screenshotOptions = { path: `./dist/${number++}.png`, clip: { x: boundingBox.x, y: boundingBox.y, width: boundingBox.width, height: boundingBox.height } }; // debug // await new Promise(resolve => process.stdin.once('data', resolve)); await page.screenshot(screenshotOptions); } await browser.close(); })();