Search code examples
javascriptnode.jsscreenshotpuppeteerscreen-scraping

puppeteer : The first link work, the others dont


this is my first post. Im learning JS with Nodejs. So I saw the Puppeteer script to take screenshot of the elements and I copy and change it. But have some problems here.


        const express = require('express')

        const app = express()
        const port = 3000

        app.get('/', (req, res) => res.send('Veamos Kia!'))

        app.listen(port, () => console.log(`App de ejemplo escuchando el puerto ${port}!`))
        app.get("/scrapping", function (req, res) {
            res.send('Estamos listos para empezar');
        })

        const puppeteer = require("puppeteer");
        const mkdirp = require('mkdirp')

        
        //Vemos y formateamos la fecha en la que las capturas se hacen
        let date = new Date()

        let day = date.getDate()
        let month = date.getMonth() + 1
        let year = date.getFullYear()

        if(month < 10){
        console.log(`${day}-0${month}-${year}`)
        }else{
        console.log(`${day}-${month}-${year}`)
        }
        //fecha formateada a DD/MM/AAAA
        let dateFormat = `${day}${month}${year}`;

        //fecha formateada todo seguido
            let dateNumber = Number(date);
            const fs = require("fs");



            //ES LA BASE


            //const puppeteer = require('puppeteer');           // include lib
            (async () => {                                    // declare function
                const browser = await puppeteer.launch({'defaultViewport' : { 'width' : 1920, 'height' : 545 }});       // run browser
                const page = await browser.newPage();           // open new tab
                const navigationPromise = page.waitForNavigation()

                await page.goto('https://www.fiat.cl/modelo/ducato-pasajeros/ducato-pasajeros-precios-y-versiones/#top'); 
                
                     

                await page.waitForSelector('div.small-12.large-12.columns.container');          // wait for the selector to load
                let element = await page.$('div.small-12.large-12.columns.container');        // declare a variable with an ElementHandle
                await element.screenshot({path: `fiat/${dateFormat}/1.png`}); // take screenshot element in puppeteer
                

                await page.goto('https://www.fiat.cl/modelo/argo/argo-precios-y-versiones/#top'); 
                await navigationPromise
                
                     

                await page.waitForSelector('div.small-12.large-12.columns.container');          // wait for the selector to load
                
                await element.screenshot({path: `fiat/${dateFormat}/2.png`}); // take screenshot element in puppeteer

                await browser.close();                          // close browser
    })();


The log throw me this; "(node:17856) UnhandledPromiseRejectionWarning: Error: Node is either not visible or not an HTMLElem"

The first screenshot is ok but the second has the error. What am I doing wrong? Sorry for my grammatical mistakes, Im not an english speaker but I´m trying to improve it day by day.


Solution

  • Most likely second screenshot does not work, because you've got a handle to an old element which is no longer accessible (you navigated to other page already). You have to re-initialize the element variable:

    const express = require('express')
    
    const app = express()
    const port = 3000
    
    app.get('/', (req, res) => res.send('Veamos Kia!'))
    
    app.listen(port, () => console.log(`App de ejemplo escuchando el puerto ${port}!`))
    app.get("/scrapping", function (req, res) {
        res.send('Estamos listos para empezar');
    })
    
    const puppeteer = require("puppeteer");
    const mkdirp = require('mkdirp')
    
    
    //Vemos y formateamos la fecha en la que las capturas se hacen
    let date = new Date()
    
    let day = date.getDate()
    let month = date.getMonth() + 1
    let year = date.getFullYear()
    
    if(month < 10){
    console.log(`${day}-0${month}-${year}`)
    }else{
    console.log(`${day}-${month}-${year}`)
    }
    //fecha formateada a DD/MM/AAAA
    let dateFormat = `${day}${month}${year}`;
    
    //fecha formateada todo seguido
        let dateNumber = Number(date);
        const fs = require("fs");
    
    
    
        //ES LA BASE
    
    
        //const puppeteer = require('puppeteer');           // include lib
        (async () => {                                    // declare function
            const browser = await puppeteer.launch({'defaultViewport' : { 'width' : 1920, 'height' : 545 }});       // run browser
            const page = await browser.newPage();           // open new tab
            const navigationPromise = page.waitForNavigation()
    
            await page.goto('https://www.fiat.cl/modelo/ducato-pasajeros/ducato-pasajeros-precios-y-versiones/#top');
    
    
    
            await page.waitForSelector('div.small-12.large-12.columns.container');          // wait for the selector to load
            let element = await page.$('div.small-12.large-12.columns.container');        // declare a variable with an ElementHandle
            await element.screenshot({path: `1.png`}); // take screenshot element in puppeteer
    
    
            await page.goto('https://www.fiat.cl/modelo/argo/argo-precios-y-versiones/#top');
            await navigationPromise
    
    
    
            await page.waitForSelector('div.small-12.large-12.columns.container');          // wait for the selector to load
            let elementAfterNavigation = await page.$('div.small-12.large-12.columns.container');        // re-initialize element!
            await elementAfterNavigation.screenshot({path: `2.png`}); // take screenshot element in puppeteer
    
            await browser.close();                          // close browser
    })();
    

    Notice the elementAfterNavigation. This is why such functionality (eg. single screenshot) deserves its own function with scoped variables.