Implementación de un proyecto NestJS de WebScrapping (Puppeteer) en AWS Lambda
Puppeteer — Después de algunos meses de intentar ejecutar un proyecto de web scrapping de NestJs dentro de un AWS Lambda, finalmente obtuve la solución.
Estaba usando https://github.com/adieuadieu/serverless-chrome, así que noté que AWS por defecto no tiene fuentes del sistema, necesitaba configurarlo manualmente. Por eso, estaba teniendo este problema:
2022–04–13T13:04:46.622Z 9b8249dc-60ad-560c-a06f-130cac3fd345 INFO @serverless-chrome/lambda: Error trying to spawn chrome: Error: connect ECONNREFUSED 127.0.0.1:9222 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16) { errno: ‘ECONNREFUSED’, code: ‘ECONNREFUSED’, syscall: ‘connect’, address: ‘127.0.0.1’, port: 9222}
DevTools listening on ws://127.0.0.1:9222/devtools/browser/b3db09ab-4250-4c63-be21-07eb1eeefa3d [0413/133945.501862:FATAL:platform_font_skia.cc(97)] Check failed: InitDefaultFont(). Could not find the default font
Para saber más sobre el error lo publiqué aquí:
https://github.com/adieuadieu/serverless-chrome/issues/335
Después de un tiempo de búsqueda, finalmente pude encontrar otra solución, necesitaba usar “chrome-aws-lambda”, esta biblioteca ya tiene configuradas las fuentes del sistema, lo que puede ser un acceso directo a nuestro trabajo. Asumiré que ya tienes un titiritero en tu proyecto.
Para instalar necesitas ejecutar:
npm install chrome-aws-lambda — save-prod
Creé este tutorial con dos formas de usar Puppeteer, usando el titiritero puro o usando el titiritero extra (¿Cuál es el mejor? Depende de cuál sea tu propósito).
1 — Si usas Titiritero puro puedes usar el siguiente código:
const chromium = require('chrome-aws-lambda'); exports.handler = async (event, context, callback) => { let result = null; let browser = null; try { browser = await chromium.puppeteer.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath: await chromium.executablePath, headless: chromium.headless, ignoreHTTPSErrors: true, }); let page = await browser.newPage(); await page.goto(event.url || 'https://example.com'); result = await page.title(); } catch (error) { return callback(error); } finally { if (browser !== null) { await browser.close(); } } return callback(null, result); };
2 — Si usa Puppeteer Extra para tener complementos, puede usar el siguiente código:
const chromium = require('chrome-aws-lambda'); const { PuppeteerExtra } = require('puppeteer-extra'); exports.handler = async (event, context, callback) => { let result = null; let browser = null; try { const puppeteerExtraInstance = new PuppeteerExtra(chromium.puppeteer, undefined); puppeteerExtraInstance.use(pluginXYZ); browser = await puppeteerExtraInstance.launch({ args: chromium.args, defaultViewport: chromium.defaultViewport, executablePath: await chromium.executablePath, headless: chromium.headless, ignoreHTTPSErrors: true, }); let page = await browser.newPage(); await page.goto(event.url || 'https://example.com'); result = await page.title(); } catch (error) { return callback(error); } finally { if (browser !== null) { await browser.close(); } } return callback(null, result); };
Uno de estos códigos antes garantizará que tiene cromo y un titiritero con fuentes del sistema y se lanzará en AWS Lambda.
Si obtiene algo como la imagen de arriba, su web scrapping dentro de lambda se estará ejecutando:
¡Espero que esto ayude!