Coding session 4 - un web crawler avec Puppeteer
2 min read

Coding session 4 - un web crawler avec Puppeteer

Date de la session : 19/08/2021 18h30-00h00++

Date de publication : 22/09/2021

Intro

Exécution du deuxième script.

deuxième script crawler allphotolenses
deuxième script crawler allphotolenses

Description

Parfois, ça plante.

Mais grâce aux logs, il suffit de récupérer le nombre de l'itération qui a planté, et replacer la boucle for à l'endroit ou ça à planté.

script faillure-edited.gif
script failure

Lors de ma recherche de base de données, j'ai enfin trouvé le bon terme de recherche pour Google. "digital camera database".

Je suis tombé sur ce site. teoalida.com/database/digitalcameras

C'est apparemment quelqu'un qui c'est spécialisé dans le scraping de site web. Il propose les données du site digicamdb.com. Contre un paiement de $75.32, marrant, c'est ma prochaine cible.

teoalida-digital-camera-database.PNG

Site très intéressant, je m'arrête là pour ce soir, il faut que visite plus en profondeur ce fameux site Wordpress teoalida.com

Objectifs

  • Faire fonctionner le 2ième Crawler

Code

2ième script.

Récupère les informations sur l'objectif.

  • 'Name', 'Focal length', 'Max. aperture', 'Min. aperture', 'Blades', 'Min. Focus (m.)', 'Filter Ø (mm.)', 'Weight (gr/oz)', 'Length (mm/in)', pictures
import { chromium } from 'playwright';
import * as fs from "fs";
const pages = require("./paths.json");

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    // START
    let results: any[][] = [
        [
            'Name',
            'Focal length',
            'Max. aperture',
            'Min. aperture',
            'Blades',
            'Min. Focus (m.)',
            'Filter Ø (mm.)',
            'Weight (gr/oz)',
            'Length (mm/in)'
        ]
    ];
    let fileNumber = 0;

    console.time('time_elapsed')
    for (let i = 526; i < pages.length; i++) {
        await page.goto(pages[i], { waitUntil: 'networkidle', timeout:40000});
        console.log("iteration ", i, pages[i])
        let infos: any[] = await page.$$eval('strong', elementStrong => {
            let values: string[] = [];
            //let parentElement = elementStrong.find(el => el.textContent === 'Specifications:')
            // let elementTh = elementStrong.filter(el => el.textContent === 'Specifications:')[0].parentElement.querySelectorAll('th');
            // headers = Array.from(elementTh).map(th => th.textContent)
            let elementTd = elementStrong.filter(el => el.textContent === 'Specifications:')[0].parentElement.querySelectorAll('td');
            values = Array.from(elementTd).map(r => r.textContent)
            return values;
        })
        let name: string = await page.$eval('h1', h1 => {
            return h1.textContent;
        })
        let pictures: string[] = await page.$$eval('strong', elementStrong => {
            let values: string[] = [];
            let elementTd = elementStrong.filter(el => el.textContent === 'Pictures')[0].parentElement.querySelectorAll('a');
            values = Array.from(elementTd).map(r => '<http://allphotolenses.com>' + r.getAttribute('href'))
            return values;
        })
        let pics = {
            pictures: pictures
        };
        infos.push(pics);
        // rotate file
        let r = await page.evaluate(({ results, name, infos, fileNumber }) => {

            if (results.length == 100) {
                fileNumber = fileNumber + 1;
                results = [];
            }
            results.push([name].concat(infos));
            return { fileNumber, results }
        }, { results, name, infos, fileNumber });
        results = r.results;
        fileNumber = r.fileNumber
        console.log("write to file ", r.fileNumber, results.length)
        fs.writeFileSync(`./results/lenses-${r.fileNumber}.json`, JSON.stringify(r.results));
    };
    console.log("results length", results.length);
    console.log("results :", results);

    // END
    console.timeEnd('time_elapsed');
    await browser.close();
})();

Difficultés rencontrées

  • Trouver la bonne technique pour traverser le DOM
  • Le script plante parfois pour accéder à une page. Lié à une erreur de chargement de la page. Cela induit une opération manuelle pour relancer le crawl. 😑

Points positifs

  • 2ième script exécution ok partielle.

Nouvelles problématiques

Fixer les erreurs de chargement de la page lors de l'exécution du script.

Prochaines étapes

Crawler digicamdb.com.

Enjoying these posts? Subscribe for more