Partage
  • Partager sur Facebook
  • Partager sur Twitter

[NodeJs] Problème de génération d'un fichier JSON

Anonyme
    2 mai 2018 à 16:58:55

    Bonjour à tous.

    Alors voilà, je me retrouve face à un petit problème. J'essai de générer un fichier Json "dynamiquement", sauf que je n'arrive pas à obtenir un résultat exploitable par la suite. J'ai rechercher sur le net, testé plusieurs solutions, mais rien n'y fait, le résultat du fichier Json obtenu est invalide.

    Mes contraintes :
    Il faut que je traite les informations de +16K de pages de produits. Et ce de façon asynchrone, histoire d’accélérer le traitement des données ( comparé à mon script PHP ).

    Ce que j'ai fais :
    Ajouter les données dans un tableau, puis transformer le tableau en JSON et le sauvegarder est impossible. Sur un échantillon de produits cela fonctionne, mais sur l'ensemble, j'arrive vite à une saturation de mémoire.
    J'ai donc opté pour les streams et le package JSONStream

    Voici l'extrait de mon code.

    var idProds = ['124727' , '124719' , '117592' , '126158' , '102373' , '120760' , '108868' , '109129' , '83460' , '122116' , '116482' , '126070' , '123625' , '123017' , '128251' , '125843' , '83498' , '123596' , '125563' , '120573' , '123588' , '125408' , '126793' , '127689' , '125545' , '127662' , '121892'];
        var transformStream = JSONStream.stringify(open='{\n', sep='\n,\n', close='\n}\n');
        var outputStream = fs.createWriteStream( __dirname + "/datatest.json" );
    
        transformStream.pipe( outputStream );
    
        async.eachLimit(idProds, 10, function (idProd, callback) {
            var requestOptions  = { encoding: null, method: "GET", uri: urlWebsite + idProd + "-lorem.html"};
            request(requestOptions, function(error, response, body) {
                if(error){
                    console.log(error);
                    return;
                }
                try {
                    var idProdArray = {};
                    var data = iconv.decode(new Buffer(body), "ISO-8859-1");
                    const dom = htmlparser2.parseDOM(data);
                    const $ = cheerio.load(dom);
    
                    idProdArray['ariane'] = [];
                    $('#fil_arianne .bloc_arianne a').each(function( index ) {
                        idProdArray['ariane'].push( $( this ).text() );
                    });
                    idProdArray['nom'] =  $('#contenu h1[itemprop="name"]').text();
                    idProdArray['eco'] =  $('#contenu .eco_participation').text();
                    idProdArray['desc'] =  $('#contenu .caracteristique').html();
                    idProdArray['img'] = [];
                    $('a.photo_produit').each(function( index ) {
                        idProdArray['img'].push($( this ).attr('href'));
                    });
                    transformStream.write( {[idProd] : idProdArray} )
                    console.log('Produit '+ idProd +' enregistré');
                    callback();
                } catch (error) {
                    console.log(error);
                    return;
                }
            });
        }, function(err) {
            if( !err ) {
                transformStream.end();
            }
        });

    Ce que j'obtiens :

    {
    {"102373":{"ariane":["a","b","c"],"nom":"premier produit","eco":"\n\t\t+ 1,00  d'éco-participation\n\t\t","desc":"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci est natus distinctio repellendus ratione aliquid maiores incidunt unde commodi consectetur nisi obcaecati perferendis perspiciatis fuga, qui blanditiis. Soluta, nisi velit.","img":["img/produit/800/produit_img1.jpg","img/produit/800/produit_img2.jpg"]}}
    ,
    {"124719":{"ariane":["a","b","e"],"nom":"second produit","eco":"\n\t\t+ 1,00  d'éco-participation\n\t\t","desc":"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Pariatur eos perspiciatis fuga quae saepe, in est cumque ratione ea totam eligendi, atque tenetur nobis debitis aut ipsa voluptatibus odit cupiditate","img":"[img/produit/800/produit_img1.jpg","img/produit/800/produit_img2.jpg"]}}
    ,
    [.....]
    }

    Comme vous poucvez le voir, le premier élément de mon Json est un objet {}, hors, je voudrais avoir l'identifiant du produit...
    Ce que j'aimerais obtenir :

    {
    "102373":{"ariane":["a","b","c"],"nom":"premier produit","eco":"\n\t\t+ 1,00  d'éco-participation\n\t\t","desc":"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci est natus distinctio repellendus ratione aliquid maiores incidunt unde commodi consectetur nisi obcaecati perferendis perspiciatis fuga, qui blanditiis. Soluta, nisi velit.","img":["img/produit/800/produit_img1.jpg","img/produit/800/produit_img2.jpg"]}
    ,
    "124719":{"ariane":["a","b","e"],"nom":"second produit","eco":"\n\t\t+ 1,00  d'éco-participation\n\t\t","desc":"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Pariatur eos perspiciatis fuga quae saepe, in est cumque ratione ea totam eligendi, atque tenetur nobis debitis aut ipsa voluptatibus odit cupiditate","img":"[img/produit/800/produit_img1.jpg","img/produit/800/produit_img2.jpg"]}
    ,
    [.....]
    }

    Avez vous des idées ou suggestions ?

    De plus, secondairement, j'ai l'impression que même si mon traitement s'effectue dans  "async.eachLimit", les produits ne sont traité que 1 par 1, en fil d'attente, et non 10 par 10... Juste une impression ? Ou j'ai effectivement un problème dans mon script ?

    En vous remerciant.

    -
    Edité par Anonyme 2 mai 2018 à 16:59:34

    • Partager sur Facebook
    • Partager sur Twitter

    [NodeJs] Problème de génération d'un fichier JSON

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown