Как использовать setinterval в узле Puppeteer js - PullRequest
0 голосов
/ 14 мая 2019

Я хочу остановить свой скрипт и подождать до конца, а затем вернуть массив. Он не должен двигаться вперед без возвратного элемента в узле кукловода js. Он не ждет очищенного интервала и движется вперед, так что я получаю неопределенное значение, как ждать результата массива здесь.

Я получаю неопределенный результат. Я хочу получить массив.

const puppeteer = require("puppeteer");
var page;
var browser;
async function getuser_data(callback) {
    browser = await puppeteer.launch({
        headless: false,
        args: ["--no-sandbox", "--disable-setuid-sandbox"]
    });
    page = await browser.newPage();
    await page.setViewport({
        width: 1068,
        height: 611
    });
    await page.goto(
        "https://www.instagram.com/accounts/login/?source=auth_switcher"
    );
    await page.waitForSelector('input[name="username"]');
    await page.type('input[name="username"]', "yourusername");
    await page.type('input[name="password"]', "yourpassword");
    await page.click("._0mzm-.sqdOP.L3NKy");

    await page.waitFor(3000);
    var y = "https://www.instagram.com/xyz/";
    await page.goto(y);
    await page.waitFor(2000);

    var c = await page.evaluate(async () => {
        await document
            .querySelector(
                "#react-root > section > main > div > header > section > ul > li:nth-child(2) > a"
            )
            .click();
        var i = 0;
        var timer = await setInterval(async () => {
            i = i + 1;
            console.log(i);
            await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
            var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
                .length;
            console.log("Now length is :" + ele);
            console.log("Timer :" + i);

            if (ele > 10 && i > 20) {
                console.log("Break");
                clearInterval(timer);
                console.log("after break");
                var array = [];
                for (var count = 1; count < ele; count++) {
                    try {
                        var onlyuname = await document.querySelector(
                            `body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
                        ).innerText;
                        console.log(onlyuname);
                        var obj = {
                            username: onlyuname
                        };
                        console.log(obj);
                        await array.push(obj);
                    } catch (error) {
                        console.log("Not found");
                    }
                }
                console.log(JSON.stringify(array));
                return array;   //Should Wait Till return , it should not move forward
            }
        }, 800);
    });
    console.log(c)  //IT should return me array, Instead of undefined
    callback(c)
}

getuser_data(users => {
    console.log(users)
    let treeusernamefile = JSON.stringify(users);
    fs.writeFileSync('tablebay.json', treeusernamefile);
})

Ответы [ 2 ]

2 голосов
/ 15 мая 2019

Проблема в том, что setInterval() работает не так, как вы ожидаете.В частности, он не возвращает Promise, который вы могли бы await.Он синхронно создает интервал, и затем возвращается вся функция, которую вы передаете page.evaluate().

Что вам нужно сделать, это создать Promise самостоятельно и сообщить ему resolve, как только вы получитеarray ready.

//...

return new Promise((resolve, reject) => {
    var timer = setInterval(async () => {
            i = i + 1;
            console.log(i);
            await document.querySelector(".isgrP").scrollBy(0, window.innerHeight);
            var ele = await document.querySelectorAll(".FPmhX.notranslate._0imsa ")
                .length;
            console.log("Now length is :" + ele);
            console.log("Timer :" + i);

            if (ele > 10 && i > 20) {
                console.log("Break");
                clearInterval(timer);
                console.log("after break");
                var array = [];
                for (var count = 1; count < ele; count++) {
                    try {
                        var onlyuname = await document.querySelector(
                            `body > div.RnEpo.Yx5HN > div > div.isgrP > ul > div > li:nth-child(${count}) > div > div.t2ksc > div.enpQJ > div.d7ByH > a`
                        ).innerText;
                        console.log(onlyuname);
                        var obj = {
                            username: onlyuname
                        };
                        console.log(obj);
                        await array.push(obj);
                    } catch (error) {
                        console.log("Not found");
                    }
                }
                console.log(JSON.stringify(array));
                resolve(array);   // <-----------------
            }
        }, 800);
})

//...

Обратите внимание, что приведенный выше пример не обрабатывает ошибки.Если какая-либо из функций в вашем setInterval сгенерирует, вам нужно отловить эти ошибки и передать их во внешнюю область с помощью reject.

Надеюсь, это поможет.

0 голосов
/ 15 мая 2019

setTimeout, обещания и рекурсивные функции могут быть полезны.

// a normal delay function, you can call this with await
const delay = d => new Promise(r => setTimeout(r, d))

const data = [];

async function timer(i = 0) {
  // Optionally set to wait 1000 ms and then continue
  await delay(1000)

  // click element, grab data etc.
  console.log(`Clicking element ${i}`);
  data.push(i);

  // check for condition fulfillment, you can basically put any limit here
  if (i >= 10) return data;

  // return another promise recursively here
  return timer(i + 1)
}

timer().then(console.log)

Запустите фрагмент кода, чтобы увидеть в действии. Он должен рекурсивно показывать консоль, пока она не достигнет определенного предела.

Как это работает, он вернет другое обещание, если условие еще не выполнено. Вы можете вызывать его бесконечно и очистить тайм-аут (он же возвращает данные вместо другого обещания таймера).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...