Dnes jen krátce, přesto však výstižně, prakticky a třeba to někomu pomůže v budoucnu. Řešil jsem totiž jak jednodušše stáhnout více souborů z internetu. Konkrétně se jednalo o více jak 180 epizod uložených v MP3kách z podcastu Startups For the Rest of Us (který mimochodem vřele doporučuji). První nápad byl samozřejmě začít zuřivě klikat a ukládat jeden soubor za druhým, po chvíli mi ale došlo, že tudy cesta nevede. Vzpoměl jsem si na node.js a jeho asynchronní zpracování a řekl si, že toto je přesně případ, kdy se mi může hodit.
Během chvilky se totiž v Nodu dá napsat jednoduchý script, který se o vše postará a jako bonus může soubory stahovat hezky paralelně. Vybral jsem hlavní části scriptu, které zde chci ukázat a zbytek i s návodem jsem hodil na github.
function download(id, done) { var link = url + lZeroPad(id) + urlTld; // url ze ktereho budeme stahovat var fileName = link.split("/"); fileName = fileName[fileName.length -1]; // nazev souboru, pod kterym MP3ku ulozime console.log(" > Downloading ID: "+ id, fileName); var file = fs.createWriteStream("downloads/" + fileName); // otevreme soubor pro ulozeni var request = http.get(link, function(response) { // z URL stahneme soubor response.pipe(file); // a ulozime ho do otevreneho souboru console.log(" < Downloaded ID: ", id); done(null); // rekneme asyncu, ze muze zacit stahovat dalsi soubor }); } function downloadAll(all) { // vytvorime slozku pro ulozeni vysledku mkdirp('downloads', function(err) { // asynchronne spustime stahovani pro vsechny soubory s omezenim na max X soucasnych stahovani // abychom nepretezovali zdrojovy server ;-) async.eachLimit(all, CONCURENCY, download, function() { console.log( "====== Downloaded ALL ======" ); }); }); } downloadAll(allFiles);
První funkce má na sarost stažení jednoho souboru, ta druhá pak pomocí knihovny async spustí stahování pro jednotlivé soubory. Za zmínku ještě stojí použitá metoda eachLimit, která omezí počet současně stahovaných souborů na danou hodnotu, abychom nezatěžovali server ze kterého taháme data.
Skript postahoval všech 186 epizod (cca 7giga) do složky downloads bez větších problémů a díky svému asynchronnímu zpracování mi i ušetřil čas.
Pro zájemce jsem celý script i s návodem hodil na git a doufám, že se případně bude hodit i dalším, kteří by narazili na stejný problém.
Detailnější použití knihovny async jsem popsal na portálu nodejs.cz, kde se věnuji také dalším funkcím, které nám async nabízí. Pokud si chcete udělat představu o tom, co Node.JS dokáže, tak doporučuji… :-)