Puppeteer 实战教程 - 爬取 Github 高星项目数据

简介: 本文通过爬取 Github 高星数据项目讲解了 Puppeteer 的入门知识,包括浏览器启动、页面访问、页面数据提取、页面交互等,利用这些知识你可以用 Puppeteer 自动化你的日常工作。

Puppeteer 是 Google 开源的一个用于操作浏览器的库,可以用于爬虫、自动化测试等。Puppeteer 的本义是“提线木偶”,因此可以把它理解为代替我们去操作浏览器的一个机器人,例如我想收集 Github 上 stars 数量前 100 名的项目数据,包括项目名称、项目链接、项目 stars 数量、项目描述、项目语言和项目标签,如果手动的一个一个录入数据就太麻烦了,这个时候我们就可以利用 Puppeteer 来帮助我们。

环境准备

新建一个文件夹,输入以下命令安装 Puppeteer:

npm install puppeteer

爬取 Github 项目数据

首先我们要知道如何搜索得到 Github stars 数前一百的项目,这可以通过 Github 的高级搜索符来实现。我们在 Github 输入框输入 stars:>10000,然后搜索。这个搜索符的含义是找到所有 star 数量大于一万的项目。

在搜索结果出来之后,我们点击右上角的筛选,把搜索结果改为按 stars 数量排序。

2023-07-23-14-44-53.png

可以看到项目列表中的每一项包含了我们所需要获取的各项信息,接下来就可以编写代码来帮助我们完成数据爬取的任务了。

首先我们导入 Puppeteer,然后启动一个浏览器,并让它访问我们搜索得到的页面:

const browser = await puppeteer.launch();

const page = await browser.newPage();
await page.goto(
  "https://github.com/search?q=stars:%3E100&type=repositories&s=stars&o=desc"
);

然后我们通过 page.evaluate() 函数来获取页面上的项目数据。

const projects = page.evaluate(() => {
   
   
  // 获取各个项目对应的元素
  const repos = document.querySelectorAll(".jUbAHB");
  // 遍历各个项目元素,提取其中的项目数据
  const data = [...repos].map((repo) => {
   
   
    const title = repo.querySelector("h3").innerText;
    const link = repo.querySelector(".fIqerb").href;
    const description = repo.querySelector(".kWPXhV").innerText;
    const language =
      repo.querySelector('[aria-label*="language"]')?.innerText || "";
    const tags = Array.from(repo.querySelectorAll(".cvduTM")).map(
      (e) => e.innerText
    );
    const stars = repo.querySelector('[aria-label*="stars"]').innerText;
    return {
   
   
      title,
      link,
      description,
      language,
      stars,
      tags,
    };
  });

  return data;
});

page.evaluate() 的回调函数中的代码会在打开的页面中被执行,也就是说我们可以在其中访问页面的 dom 元素,从而获取到我们所需要的数据。这里我们首先获取了每一个项目对应的 dom 元素,然后从各个项目的 dom 元素中收集其信息,最后返回得到的数据。

这里每项数据对应的 dom 元素可以通过开发者工具查看,首先右键点击页面然后选择“检查”,打开 Elements/元素 Tab,点击左上角的箭头 icon。

2023-07-23-14-58-20.png

此时把鼠标放到页面中的任意元素上,开发者工具中就会显示出该元素对应的标签信息。以项目的描述为例,我们可以看到该元素对应的 class 中有一个 kWPXhV,那么我们就可以通过 .kWPXhV 这个选择器来获取到该元素,然后用innerText获取项目描述的内容。

2023-07-23-15-05-14.png

有些元素的 class 可能会和其他的元素重复,这时可以尝试通过其他的属性来获取该元素,例如项目 stars 数量的 class 就和项目语言的 class 相同,那么就可以用 aria-label 来获取这两个元素。通过 [aria-label*="language"] 这个选择器来获取 aria-label 属性中包含 language 的元素,该元素的 innerText 就是项目语言的数据。

2023-07-23-15-08-00.png

此时我们只是获取了前 10 个项目的数据,但我们想要的是前 100 的项目数据,所以还需要在每一页的数据获取完成后进入下一页,重复 10 次。我们可以点击进入项目列表的下一页,观察 url,会发现多了一个 p=2 的参数,因此我们只需要循环改变 url 中 p 参数的数值就可以访问前十页的数据了。

const projects = [];
for (let i = 1; i <= 10; i++) {
   
   
  await page.goto(
    `https://github.com/search?q=stars:%3E100&type=repositories&s=stars&o=desc&p=${
     
     i}`
  );
  const currentPageProjects = await page.evaluate(() => {
   
   
    // ...
  });

  projects.push(...currentProjects);
}

最后我们可以把收集到的数据保存到一个 json 文件中方便使用。

const fs = require("fs");
fs.writeFileSync("projects.json", JSON.stringify(projects));

完整的项目代码如下:

const puppeteer = require("puppeteer");
const fs = require("fs");

(async () => {
   
   
  const browser = await puppeteer.launch();

  const page = await browser.newPage();
  await page.goto(
    "https://github.com/search?q=stars:%3E100&type=repositories&s=stars&o=desc"
  );

  const projects = [];
  for (let i = 0; i < 10; i++) {
   
   
    const currentPageProjects = await page.evaluate(() => {
   
   
      const repos = document.querySelectorAll(".jUbAHB");
      const data = [...repos].map((repo) => {
   
   
        const title = repo.querySelector("h3").innerText;
        const link = repo.querySelector(".fIqerb").href;
        const description = repo.querySelector(".kWPXhV").innerText;
        const language =
          repo.querySelector('[aria-label*="language"]')?.innerText || "";
        const tags = Array.from(repo.querySelectorAll(".cvduTM")).map(
          (e) => e.innerText
        );
        const stars = repo.querySelector('[aria-label*="stars"]').innerText;
        return {
   
   
          title,
          link,
          description,
          language,
          stars,
          tags,
        };
      });

      return data;
    });

    console.log(1234);
    const link = await page.$('[rel="next"]');
    await link.click();

    projects.push(...currentPageProjects);
  }

  fs.writeFileSync("projects.json", JSON.stringify(projects));

  await browser.close();
})();

总结

本文通过爬取 Github 高星数据项目讲解了 Puppeteer 的入门知识,包括浏览器启动、页面访问、页面数据提取、页面交互等,利用这些知识你可以用 Puppeteer 自动化你的日常工作,比如进行数据爬取、自动化 UI 测试等等。

本文作者 wzkMaster,有帮助的话欢迎点赞收藏关注哦~

相关文章
|
2月前
|
编解码 Oracle Java
java9到java17的新特性学习--github新项目
本文宣布了一个名为"JavaLearnNote"的新GitHub项目,该项目旨在帮助Java开发者深入理解和掌握从Java 9到Java 17的每个版本的关键新特性,并通过实战演示、社区支持和持续更新来促进学习。
91 3
|
4月前
|
存储 安全 Java
【事故】记一次意外把公司项目放到GitHub并被fork,如何使用DMCA下架政策保障隐私
在一次意外中,作者因三年前将测试代码遗忘在GitHub上而遭遇了代码被他人fork的问题。为解决这一危机,作者详细介绍了如何通过GitHub的DMCA下架通知流程安全删除敏感代码,包括处理私人信息和商标侵权的具体步骤。本文不仅提供了实用的操作指南,还强调了及时响应的重要性,帮助读者避免类似风险
70 1
【事故】记一次意外把公司项目放到GitHub并被fork,如何使用DMCA下架政策保障隐私
|
4月前
|
SQL JavaScript 前端开发
Github 2024-08-05 开源项目周报 Top15
根据 Github Trendings 的统计,本周(2024年8月5日统计)共有15个项目上榜。以下是根据开发语言汇总的项目数量: - Go 项目:4个 - JavaScript 项目:3个 - Python 项目:3个 - Java 项目:2个 - TypeScript 项目:2个 - C 项目:1个 - Shell 项目:1个 - Dockerfile 项目:1个 - 非开发语言项目:1个
151 2
|
4月前
|
人工智能 Rust JavaScript
Github 2024-08-26 开源项目周报Top15
根据Github Trendings的统计,本周共有15个项目上榜。以下是按开发语言汇总的项目数量:Python项目8个,TypeScript、C++ 和 Rust 项目各2个,Jupyter Notebook、Shell、Swift 和 Dart 项目各1个。其中,RustDesk 是一款用 Rust 编写的开源远程桌面软件,可作为 TeamViewer 的替代品;Whisper 是一个通用的语音识别模型,基于大规模音频数据集训练而成;初学者的生成式人工智能(第2版)则是由微软提供的18门课程,教授构建生成式AI应用所需的知识。
147 1
|
4月前
|
Rust Dart 前端开发
Github 2024-08-19 开源项目周报Top15
根据Github Trendings的统计,本周(2024年8月19日统计)共有15个项目上榜。按开发语言分类,上榜项目数量如下:Python项目最多,有7项;其次是JavaScript和TypeScript,各有3项;Dart有2项;HTML、PowerShell、Clojure和C++各1项。此外,还介绍了多个热门项目,包括Bootstrap 5、RustDesk、ComfyUI、易采集、Penpot等,涵盖了Web开发、远程桌面、自动化测试、设计工具等多个领域。
123 1
|
4月前
|
JavaScript 前端开发 Go
Github 2024-08-12 开源项目周报 Top14
本周Github Trendings共有14个项目上榜,按开发语言汇总如下:Python项目7个,TypeScript项目5个,C项目2个,JavaScript项目2个,Go和Batchfile项目各1个。其中亮点包括开发者职业成长指南、Windows激活工具、ComfyUI图形界面、AFFiNE知识库、易采集可视化爬虫等项目,涵盖多种实用工具和开源平台。
158 1
|
4月前
|
存储 JavaScript 前端开发
Github 2024-07-29 开源项目周报Top15
根据 Github Trendings 的统计,本周(2024年7月29日统计)共有15个项目上榜。按开发语言分类,项目数量如下:Python、Java、HTML 和 C 项目各有2项;TypeScript、JavaScript、Vue 和 Go 各有1项;另有1项非特定语言项目、1项 Dart 项目、1项 C++ 项目、1项 Rust 项目及1项 Jupyter Notebook 项目。这些项目涵盖了多种领域,如API开发、照片管理、PDF处理、AI技术等。
73 1
|
4月前
|
Rust JavaScript 前端开发
Github 2024-07-15 开源项目周报 Top15
根据 Github Trendings 的统计,2024年7月15日当周共有15个项目上榜。以下是按开发语言分类的项目数量汇总:Python项目5个,非开发语言项目4个,JavaScript项目3个,TypeScript项目2个,Go、Solidity和Java项目各1个,Rust项目1个。此外,介绍了多个值得关注的项目,包括免费编程学习平台 freeCodeCamp.org、免费编程书籍和学习资源清单、免费 API 集合等,涵盖了不同编程语言和技术领域。
61 1
|
4月前
|
人工智能 JavaScript API
Github 2024-07-08 开源项目周报 Top15
根据Github Trendings的统计,本周(2024年7月8日统计)共有15个项目上榜。按开发语言分类,Python项目最多,有6项;其次是C++和TypeScript,各有3项;Jupyter Notebook和JavaScript各2项;QML、非开发语言项目、Rust则各有1项。这些项目涵盖了多种领域,包括编程教育、API集合、语言模型、十六进制编辑器等。
61 1
|
4月前
|
机器学习/深度学习 Rust JavaScript
Github 2024-06-24 开源项目周报 Top15
根据Github Trendings的统计,本周(2024年6月24日统计)共有15个项目上榜。按开发语言分类,项目数量如下:JavaScript项目5个,Python项目5个,TypeScript项目2个,Go项目2个,Dockerfile项目1个,C#项目1个,Java项目1个,Jupyter Notebook项目1个,Rust项目1个,Dart项目1个,Tcl项目1个。
50 0