Skocz do zawartości
Pecetowicz Forum komputerowe

Node.js - webscraping problem z pętlą Promise'ów


Rekomendowane odpowiedzi

  • Administrator

Witajcie

W wolnej chwili ogarniam sobie node.js i aktualnie kminię sobie webscraper piosenek z róznych stacji radiowych.

Posiadam takie bloki kodów:

Pobranie listy piosenek:

Spoiler

async function generateEskaJSON(){
    let singleSongs = [];

    await Axios.get("https://www.eska.pl/goraca20/")
    .then((response) => {
        if( response.status == 200 ){
            const $ = cheerio.load(response.data);

            $(".single-hit").find(".single-hit__title").each(async (i, el) => {
            // $(".single-hit").eq(10).find(".single-hit__title").each(async (i, el) => {
            // $(".single-hit:nth-child(1), .single-hit:nth-child(2), .single-hit:nth-child(3), .single-hit:nth-child(4), .single-hit:nth-child(5)").find(".single-hit__title").each(async (i, el) => {

                let item = $(el);
                if( item.text() != "Radio ESKA" ){
                    let title = item.text();
                    let authors = [];

                    item.next().find("a").map((a_i, a_el) => {
                        authors.push( $(a_el).text() );
                    });

                    authors = authors.join(" ");

                    singleSongs.push({
                        "id": i,
                        "title": title,
                        "authors": authors,
                        "video": {}
                    });
                }
            });
        }
    })
    .then(() => {
        let promises = [];
        singleSongs.forEach((el, i) => {
            promises.push( getYoutubeInfo(`${el.title} ${el.authors}`) );
        });
        
        Promise.all(promises).then((val) => {
            val.forEach((el, i) => {
                singleSongs[i].video = el;
            });

            fs.writeFile('eska.json', JSON.stringify(singleSongs), function (err) {
                if (err) return console.log(err);
                console.log('eska.json saved!');
            });
        });
    }).catch((err) => {
        console.error("############################# ERR0R:\n", err);
    });
}

 

Pobranie linków z Youtube (i innych dodatkowych danych):

Spoiler

async function getYoutubeInfo(query){
    console.log(query, "searching...");
    query = query.escapeDiacritics();
    query = query.split(" ").join("+");
    
    let url = "https://html.duckduckgo.com/html/?q=" + query + "+site:youtube.com";
    console.log(url);

    return await Axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20121202 Firefox/21.0' }  })
    .then((response) => {

        if( response.status == 200 ){
            const $ = cheerio.load(response.data);

            let video = $(".result").eq(0).find(".result__url").text();
            video = video.trim();

            let video_id = video.split("?v=").pop();

            let thumbnails = {
                "big": `https://img.youtube.com/vi/${video_id}/hqdefault.jpg`,
                "medium": `https://img.youtube.com/vi/${video_id}/mqdefault.jpg`,
                "small": `https://img.youtube.com/vi/${video_id}/sddefault.jpg`,
            };

            return {
                "url": video,
                "id": video_id,
                "thumbnails": thumbnails
            };
        }
        else{
            return false;
        }

    }).catch((err) => {
        console.log("");
        console.error("############################# ERROR WITH QUERY:", url, "\nREASON:", err.response.status, err.response.statusText);
    });
}

 

I o ile pierwszy blok kodu działa poprawnie, to już pojawiają się problemy przy pobraniu informacji z YT.

W terminalu wygląda to tak:

Spoiler

obraz.png

Można zauważyć że po iluś zapytaniach wyskakuje 403 - i stąd pytanie czy to moja wina czy zabezpieczenie duckducka przed spamem/ddosem?

A jeśli zabezpieczenie to jak ogarnąć spowolnienie wywołania wszystkich promisów przy pomocy Promise.all? Jest ktoś w stanie nakierować bo internet mi nie pomaga (chyba przez moje zmęczenie)?

Z góry dzięki za odpowiedzi o7

  • Lubię to! 2
Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co do opoznienia akcji https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep

A i mala uwaga co do kodu z pobieraniem linkow do yt jak uzywasz async/await to juz nie potrzebnie uzywasz then. 

Wklejam link do pastebina, bo z niewiadomych mi przyczyn nie moge zapisac posta jak dodaje ten kod https://pastebin.pl/view/74251479

 
Edytowane przez Qwizi
  • Lubię to! 1
  • Dzięki! 1
Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Administrator

Dzięki chłopaki za odpowiedzi, w wolnej chwili sprawdzę co i jak i dam znać (może nawet z gotowcem) dla przyszłych pokoleń 😉

Odnośnik do odpowiedzi
Udostępnij na innych stronach

Problem wciąż nierozwiązany? Dodaj swoją odpowiedź

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto. Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...