尝试使用 Puppeteer 抓取 twitter 时出现空数组

问题描述 投票:0回答:1

所以我试图在 Twitter 上抓取一个页面来获取推文:

我想要获取元素;文本、图像、视频分开,但我不断得到一个空数组

//Scraper.js
const puppeteer = require('puppeteer');
const fs = require('fs');

async function scrapeTwitter() {
  try {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://twitter.com/coindesk');
    await page.waitForLoadState('networkidle2');


    const html = await page.content();
    const $ = cheerio.load(html);
    const tweets = $('[data-testid="tweet"]');
    
    const posts = [];
    tweets.each(function () {
      const text = $(this).find('.tweet-text').text().trim();
      const image = $(this).find('.tweet-image').attr('src');
      const video = $(this).find('.tweet-video').attr('src');
      posts.push({ text, image, video });
    });
    
      
    await browser.close();
    
    return posts;
  } catch (error) {
    console.error('Error scraping Twitter:', error);
    return [];
  } 
}

module.exports = scrapeTwitter;
node.js web-scraping puppeteer
1个回答
0
投票

我不会将 Cheerio 与 Puppeteer 一起使用。 Puppeteer 已经可以使用实时页面,因此将整个内容序列化以转储到静态 HTML 解析器中是没有意义的。如果您想抓取更多推文,则需要向下滚动,然后重新快照整个页面,以使 Cheerio 与动态站点保持同步。

除此之外,您的选择器不会为我返回任何内容。也许尝试这样的事情:

const puppeteer = require("puppeteer"); // ^22.6.0

const url = "<Your URL>";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const tweetSel = '[data-testid="tweet"]';
  await page.waitForSelector(tweetSel);
  const data = [];

  for (let i = 0; i < 50 && data.length < 20; i++) {
    const preLen = await page.$$eval(
      tweetSel,
      els => els.length
    );
    await page.keyboard.press("PageDown");

    try {
      await page.waitForFunction(
        `document.querySelectorAll('${tweetSel}').length > ${preLen}`,
        {timeout: 2_000}
      );
    } catch (err) {
      // ...
    }

    const chunk = await page.$$eval(tweetSel, els =>
      els.map(el => ({
        text: el
          .querySelector('[data-testid="tweetText"]')
          .textContent.trim(),
        photo: el
          .querySelector('[data-testid="tweetPhoto"] img')
          ?.getAttribute("src"),
      }))
    );

    for (const e of chunk) {
      if (data.every(f => f.text !== e.text)) {
        data.push(e);
      }
    }
  }

  console.log(data);
  console.log(data.length);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
© www.soinside.com 2019 - 2024. All rights reserved.