UNPKG

website-scraper-puppeteer

Version:

Plugin for website-scraper which returns html for dynamic websites using puppeteer

82 lines (65 loc) 2.35 kB
import puppeteer from '@website-scraper/puppeteer-version-wrapper'; import logger from './logger.js'; import scrollToBottomBrowser from './browserUtils/scrollToBottom.js'; class PuppeteerPlugin { constructor ({ launchOptions = {}, gotoOptions = {}, scrollToBottom = null, } = {}) { this.launchOptions = launchOptions; this.gotoOptions = gotoOptions; this.scrollToBottom = scrollToBottom; this.browser = null; this.headers = {}; logger.info('init plugin', { launchOptions, scrollToBottom }); } apply (registerAction) { registerAction('beforeStart', async () => { this.browser = await puppeteer.launch(this.launchOptions); }); registerAction('beforeRequest', async ({requestOptions}) => { if (hasValues(requestOptions.headers)) { this.headers = Object.assign({}, requestOptions.headers); } return {requestOptions}; }); registerAction('afterResponse', async ({response}) => { const contentType = response.headers['content-type']; const isHtml = contentType && contentType.split(';')[0] === 'text/html'; if (isHtml) { const url = response.url; const page = await this.browser.newPage(); if (hasValues(this.headers)) { logger.info('set headers to puppeteer page', this.headers); await page.setExtraHTTPHeaders(this.headers); } await page.goto(url, this.gotoOptions); if (this.scrollToBottom) { await scrollToBottom(page, this.scrollToBottom.timeout, this.scrollToBottom.viewportN); } const content = await page.content(); await page.close(); // page.content() returns an already-decoded string, so we // tell website-scraper to save it as utf8. Returning a binary // string instead corrupts non-latin1 characters on disk. // See https://github.com/website-scraper/node-website-scraper#afterresponse return { body: content, encoding: 'utf8' }; } else { return response.body; } }); registerAction('afterFinish', () => this.browser && this.browser.close()); } } function hasValues (obj) { return obj && Object.keys(obj).length > 0; } async function scrollToBottom (page, timeout, viewportN) { logger.info(`scroll puppeteer page to bottom ${viewportN} times with timeout = ${timeout}`); await page.evaluate(scrollToBottomBrowser, timeout, viewportN); } export default PuppeteerPlugin;