Как очистить URL поста в Instagram с помощью puppeteer (приложение Node.js) - PullRequest
2 голосов
/ 17 октября 2019

Со всеми изменениями в текущем API Instagram я пытался построить скребок. После осмотра я нашел кукловода. Хотя это кажется довольно простым, я сталкиваюсь с проблемой, которую я не могу обернуть вокруг себя.

Проблема заключается в следующем: я знаю, что такое тег div сообщения (.v1Nh3.kIKUG._bz0w) и как это сделать. вызовите его (elements = await page.$$('.v1Nh3.kIKUG._bz0w');)

Если я правильно понимаю функцию $, это должно вернуть мне обещание, содержащее массив всех постов на странице.

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

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Чтобы получить элементы с определенным классом и вернуть их, вы должны использовать метод page.evaluate . Это асинхронный вызов, который возвращает обещание.

Итак, в вашем случае это должно выглядеть так:

const result = await page.evaluate(() => {
    let elements = document.querySelectorAll('.v1Nh3.kIKUG._bz0w');

    let elementsArr = [];
    //Loop over elements in the array and create objects from each element 
    //with the data relevant to your logic
    for (let element of elements) {
        resultArr.push({
           //your logic
        });
    }
    return elementsArr;
});
0 голосов
/ 18 октября 2019

Перво-наперво: поскольку Instagram является мощным приложением React на основе JavaScript, нужные вам селекторы могут быть недоступны сразу после загрузки страницы. Поэтому нам следует подождать, пока они появятся в DOM:

await page.waitForSelector('.v1Nh3.kIKUG._bz0w');

Теперь с page.evaluate мы получаем сообщения, но, поскольку вам нужны только ссылки внутри этих сообщений, давайте сразу же захватим их вquery:

const result = await page.evaluate(() => {
    // Get elements into a NodeList
    const elements = document.querySelectorAll('.v1Nh3.kIKUG._bz0w a');
    ...
}

Но мы не можем преобразовать элементы из Nodelist в Array и просто вернуть их, потому что они по-прежнему являются узлами DOM, сложными несериализуемыми объектами, и они должны быть serializable чтобы иметь возможность вернуться с page.evaluate. Поэтому вместо того, чтобы возвращать полные узлы, мы просто получим то, что нам нужно: urls из атрибута href:

const result = await page.evaluate(() => {
    // Get elements into a NodeList
    const elements = document.querySelectorAll('.v1Nh3.kIKUG._bz0w a');

    // Convert elements to an array, 
    // then for each item of that array only return the href attribute
    const linksArr = Array.from(elements).map(link => link.href);

    return linksArr;
});

Другие способы сделать это

В вашем вопросеВы упомянули page.$$ метод. Здесь действительно применимо получение ручек объектов, которые мы ищем. Но код для их перебора не очень приятен:

const results = await page.$$('.v1Nh3.kIKUG._bz0w a')
for (const i in results)
{
   console.log(await(await(await results[i]).getProperty("href")).jsonValue());
}

Мой любимый способ получить эти ссылки - использовать метод page.$$eval:

const results = await page.$$eval('.v1Nh3.kIKUG._bz0w a', links => links.map(link => link.href))

Это делает именното же самое, что мы сделали в page.evaluate решении, но гораздо более кратким способом.

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