首页 > 解决方案 > 从buymeacoffee网站刮掉支持者的名字

问题描述

我正在尝试从这个https://www.buymeacoffee.com/singtaousa网站上获取支持者的姓名。

目前,我能够使用axiosCheerio模块获得支持者的总数。问题是我不知道如何获得支持者的名字。

我也试过用 搜索span,没有一个支持者的名字出来。不确定我的代码是否错误或无法检索名称。

这是我的代码:

import cheerio from 'cheerio'
import axios from 'axios'

export default async function handler(req, res) {
  const { data } = await axios.get('https://www.buymeacoffee.com/singtaousa') // example
  const $ = cheerio.load(data)

  const count = $('.text-fs-16.av-medium.clr-grey.xs-text-fs-14.mg-t-8').text()
  const supporters = []

  // to be change
  $('span').each((i, element) => {
    const name = $(element).text()
    supporters.push(name)
  })

  res.status(200).json({ count, supporters })
}

标签: web-scrapingdom

解决方案


这些名称是由 JavaScript 添加的,因此您需要类似puppeteer或任何其他无头浏览器运行器之类的东西来获得基于脚本的完整页面内容。这是您使用的案例的示例puppeteer

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();

try {
  const [page] = await browser.pages();

  await page.goto('https://www.buymeacoffee.com/singtaousa');

  const namesMinimum = 20;
  const nameSelector = 'div.supp-wrapper span.av-heavy';
  const moreSelector = 'button#load-more-recent';

  await page.waitForSelector(moreSelector);

  while (await page.$$eval(nameSelector, names => names.length) < namesMinimum) {
    await Promise.all([
      page.click(moreSelector),
      page.waitForResponse(
        response => response.url().includes('www.buymeacoffee.com')
      ),
    ]);
  }

  const data = await page.evaluate(() => {
    const names = Array.from(
      document.querySelectorAll('div.supp-wrapper span.av-heavy'),
      span => span.innerText,
    );
    return names;
  });
  console.log(data);
} catch (err) { console.error(err); } finally { await browser.close(); }

推荐阅读