Strapi,另一个用例:使用 Puppeteer 从任何网站构建你自己的 API

2025-05-24

Strapi,另一个用例:使用 Puppeteer 从任何网站构建你自己的 API

本教程的目标是使用 Strapi 和 Puppeteer 构建一个简单的求职搜索 API。Strapi一个用 NodeJS 编写的开源Headless CMS ,而Puppeteer是一个基于 NodeJS 的开源Headless 浏览器(Chrome)API。

看来现在是无头工具的时代了……😆(无论如何,除了“无头”这个词之外,Strapi 和 Puppeteer 之间没有直接联系。)

斯特拉皮

Strapi 可用于轻松构建强大的 API。Strapi 提供了多种功能,包括 CRON 任务配置(这很有用,因为我们将使用它们来安排 Puppeteer 脚本的执行)。

1. Strapi 安装

好了,开始本教程吧。首先我们需要安装 Strapi。

yarn create strapi-app job-api --quickstart
Enter fullscreen mode Exit fullscreen mode

如果您不想使用,文档yarn中还有其他安装 Strapi 的可能性

2. Strapi 管理员用户

此命令应该会安装 Strapi 并打开你的浏览器。然后,你将能够创建你的管理员用户。
Strapi 管理员用户创建

3. 作业集合类型

在 Strapi 管理主页中,点击蓝色按钮CREATE YOUR FIRST CONTENT-TYPE 您将被重定向到收藏类型创建表单。
Strapi 管理员主页

Strapi 系列类型创作

之后,您将能够向 Job 集合类型添加字段。
Strapi 字段列表
Strapi 字段表单

对于我们的基本示例,我们需要创建五个文本字段(title、linkedinUrl、companyName、descriptionSnippet 和 timeFromNow)。
Strapi 职位领域

不要忘记点击“保存”按钮来重启 Strapi 服务器

Strapi 服务器重启
之后,我们可以暂时将 Strapi 管理员放在一边,并在编辑器中打开 Strapi 存储库。

Strapi CRON 任务

首先,我们需要在 Strapi 服务器配置中启用 CRON。
打开config/environments/development/server.json文件

{
  "host": "localhost",
  "port": 1337,
  "proxy": {
    "enabled": false
  },
  "cron": {
    "enabled": true
  },
  "admin": {
    "autoOpen": false
  }
}
Enter fullscreen mode Exit fullscreen mode

然后让我们创建 CRON 任务。打开~/job-api/config/functions/cron.js文件并将内容替换为以下内容

"use strict";
module.exports = {
  // The cron should display "{date} : My super cron task!" at every minute.
  "*/1 * * * *": (date) => {
    console.log(`${date} : My super cron task!\n`);
  },
};
Enter fullscreen mode Exit fullscreen mode

现在,重新启动 Strapi 服务器,让我们看看我们的 cron 任务是否正常运行。

yarn develop
yarn run v1.21.1
$ strapi develop

 Project information

┌────────────────────┬──────────────────────────────────────────────────┐
│ Time               │ Thu Apr 16 2020 01:40:49 GMT+0200 (GMT+02:00)    │
│ Launched in        │ 1647 ms                                          │
│ Environment        │ development                                      │
│ Process PID        │ 20988                                            │
│ Version            │ 3.0.0-beta.18.7 (node v10.16.0)                  │
└────────────────────┴──────────────────────────────────────────────────┘

 Actions available

Welcome back!
To manage your project 🚀, go to the administration panel at:
http://localhost:1337/admin

To access the server ⚡️, go to:
http://localhost:1337

Thu Apr 16 2020 01:41:00 GMT+0200 (GMT+02:00) : My super cron task !

Thu Apr 16 2020 01:42:00 GMT+0200 (GMT+02:00) : My super cron task !

Thu Apr 16 2020 01:43:00 GMT+0200 (GMT+02:00) : My super cron task !

...
Enter fullscreen mode Exit fullscreen mode

我们可以看到{date} : My super cron task !终端上每分钟都会显示一次。

木偶师

Puppeteer 用于自动执行您在浏览器中可以执行的任何操作。您可以使用它来自动化流程、截取屏幕截图以及生成 PDF。在本教程中,我们将使用 Puppeteer 从 Linkedin 获取 ReactJS 职位列表。我们还将使用 Cheerio 从接收到的标记中选择数据。

现在 CRON 任务运行良好,我们将在 Strapi 项目中安装 Puppeteer 和 Cheerio。

cd job-api
yarn add puppeteer cheerio 
Enter fullscreen mode Exit fullscreen mode

让我们调整 CRON 任务以获取过去 24 小时内旧金山在 linkedin 上发布的 ReactJS 职位列表

~/job-api/config/functions/cron.js

"use strict";
// Require the puppeteer module.
const puppeteer = require("puppeteer");

module.exports = {
  // Execute this script every 24 hours. (If you need to change the cron 
  // expression, you can find an online cron expression editor like 
  // https://crontab.guru
  "0 */24 * * *": async (date) => {
    // 1 - Create a new browser.
    const browser = await puppeteer.launch({
      args: ["--no-sandbox", "--disable-setuid-sandbox", "--lang=fr-FR"],
    });

    // 2 - Open a new page on that browser.
    const page = await browser.newPage();

    // 3 - Navigate to the linkedin url with the right filters.
    await page.goto(
      "https://fr.linkedin.com/jobs/search?keywords=React.js&location=R%C3%A9gion%20de%20la%20baie%20de%20San%20Francisco&trk=guest_job_search_jobs-search-bar_search-submit&redirect=false&position=1&pageNum=0&f_TP=1"
    );

    // 4 - Get the content of the page.
    let content = await page.content();
  },
};
Enter fullscreen mode Exit fullscreen mode

使用 Cheerio解析 htmlcontent并使用 Strapi 全局存储作业。

"use strict";
const puppeteer = require("puppeteer");
const cheerio = require("cheerio");

module.exports = {
  "0 */24 * * *": async (date) => {
    const browser = await puppeteer.launch({
      args: ["--no-sandbox", "--disable-setuid-sandbox", "--lang=fr-FR"],
    });
    const page = await browser.newPage();
    await page.goto(
      "https://fr.linkedin.com/jobs/search?keywords=React.js&location=R%C3%A9gion%20de%20la%20baie%20de%20San%20Francisco&trk=guest_job_search_jobs-search-bar_search-submit&redirect=false&position=1&pageNum=0&f_TP=1"
    );
    let content = await page.content();

    // 1 - Load the HTML
    const $ = cheerio.load(content);

    // 2 - Select the HTML element you need
    // For the tutorial case, we need to select the list of jobs and for each element, we will
    // create a new job object to store it in the database with Strapi.
    $("li.result-card.job-result-card").each((i, el) => {
      if (Array.isArray(el.children)) {
        const job = {
          title: el.children[0].children[0].children[0].data,
          linkedinUrl: el.children[0].attribs.href,
          companyName:
            el.children[2].children[1].children[0].data ||
            el.children[2].children[1].children[0].children[0].data,
          descriptionSnippet:
            el.children[2].children[2].children[1].children[0].data,
          timeFromNow: el.children[2].children[2].children[2].children[0].data,
        };

        // 4 - Store the job with the Strapi global.
        strapi.services.job.create(job);
      }
    });

    // 5 - Close the browser
    browser.close();
  },
};
Enter fullscreen mode Exit fullscreen mode

重启 Strapi 服务器,然后返回到管理员页面
http://localhost:1337/admin
在职位内容管理器中,你应该可以看到来自 LinkedIn 的数据。
Strapi 内容管理器列表视图
Strapi 内容管理器详细信息视图

干得好!你几分钟就从另一个网站构建了一个 API 😄

文章来源:https://dev.to/hichamelbsi/strapi-another-use-case-build-your-own-api-from-any-website-with-puppeteer-h92
PREV
2021 年全栈开发人员路线图
NEXT
调用 API 时使用 useReducer 而不是 useState!