js 爬虫抓取网页数据(2022首次更文挑战第12天:如何使用Cheerio.js和Cheerio抓取网站数据)
优采云 发布时间: 2022-04-20 16:23js 爬虫抓取网页数据(2022首次更文挑战第12天:如何使用Cheerio.js和Cheerio抓取网站数据)
“今天是我参加2022首帖更新挑战赛的第12天,活动详情见:2022首帖更新挑战”。有时您想分析来自 网站 的数据,但 网站 并未公开用于访问该数据的 API。
要获取数据,您必须求助于网络抓取。
在本文中,我将介绍如何使用 Node.js 和 Cheerio 抓取 网站 数据。
在我们开始之前,您需要遵守当地法律法规,不要随意抓取不公开的数据。
先决条件
以下是您在本教程中需要的一些东西:
什么是 Cheerio?
Cheerio 是一个在 Node.js 中解析 HTML 和 XML 的工具,在 GitHub 上非常流行,拥有超过 23k 颗星。
它快速、灵活且易于使用。由于它实现了 JQuery 的一个子集,如果您已经熟悉 JQuery,那么很容易开始使用 Cheerio。
Cheerio 和网络浏览器的主要区别在于 Cheerio 不生成视觉渲染、加载 CSS、加载外部资源或执行 JavaScript。它只是解析标记并提供用于操作结果数据结构的 API。这就解释了为什么它也非常快 - Cheerio 文档。
如果要使用cheerio抓取网页,需要先使用axios或node-fetch之类的包来抓取标记。
如何使用 Cheerio 在 Node 中抓取网页
在此示例中,我们将抓取此 Wikipedia 页面上列出的所有国家/地区和其他司法管辖区。它位于 ISO 3166-1 alpha-3 页面的当前代码部分下。
这是国家/司法管辖区列表及其相应代码的样子:
第 1 步 - 创建工作目录
在这一步中,您将通过在终端上运行以下命令为您的项目创建一个目录。此命令将创建一个名为 learn-cheerio 的文件。如果你愿意,你可以给它一个不同的名字。
mkdir learn-cheerio
复制代码
learn-cheerio成功运行上述命令后,应该可以看到一个名为created的文件夹。
在下一步中,您将在您喜欢的文本编辑器中打开刚刚创建的目录并初始化项目。
第 2 步 - 初始化项目
在这一步中,您将导航到项目目录并初始化项目。在您喜欢的文本编辑器中打开您在上一步中创建的目录,并通过运行以下命令来初始化项目。
npm init -y
复制代码
上述命令成功运行后,将在项目目录根目录下创建一个 package.json 文件。
在下一步中,您将安装项目依赖项。
第 3 步 - 安装依赖项
在此步骤中,您将通过运行以下命令来安装项目依赖项。这需要几分钟,所以请耐心等待。
npm i axios cheerio pretty
复制代码
上述命令运行成功,会在 package.json 字段下的文件中注册三个依赖项。 dependencies 第一个依赖是axios,第二个是cheerio,第三个是pretty。
axios 是一个非常流行的 http 客户端,可以在节点和浏览器中运行。我们需要它,因为cheerio 是一个分词器。
为了让 Cheerio 解析标记并获取您需要的数据,我们需要 axios 来从 网站 获取标记。如果您愿意,可以使用另一个 HTTP 客户端来获取令牌。它不一定是 axios。
pretty 是一个用于美化标记的 npm 包,以便在终端上打印时可读。
在下一节中,您将检查从中获取数据的标签。
第 4 步 - 检查您要抓取的页面
在从网页抓取数据之前,了解网页的 HTML 结构很重要。
在此步骤中,您将检查要从中抓取数据的网页的 HTML 结构。
导航至 Wikipedia 上的 ISO 3166-1 alpha-3 代码页。在“当前代码”部分下,有一个国家列表及其相应的代码。 CTRL + SHIFT + I 您可以通过按 chrome 上的组合键或右键单击并选择“检查”选项来打开 DevTools。
这是我在 chrome DevTools 中的列表:
在下一部分中,您将编写用于抓取网络的代码。
第 5 步 - 编写代码以抓取数据
在本节中,您将编写获取我们感兴趣的数据的代码。首先运行以下命令,该命令将创建 app.js 文件。
touch app.js
复制代码
成功运行上述命令会在项目目录根目录下创建一个文件app.js。
与任何其他 Node 包一样,您必须首先要求 axios、cheerio 和 .您可以通过在刚刚创建漂亮文件的文件顶部添加以下代码来做到这一点。 app.js
const axios = require("axios");
const cheerio = require("cheerio");
const pretty = require("pretty");
复制代码
在我们编写抓取数据的代码之前,我们需要学习cheerio。我们将解析下面的标记并尝试操作生成的数据结构。这将有助于我们学习 Cheerio 语法及其最常用的方法。
下面的标记是收录我们元素的 ul li 元素。
const markup = `
Mango
Apple
`;
复制代码
将上述变量声明添加到app.js文件中
如何在 Cheerio 中加载标记
cheerio 你可以使用cheerio.load 方法来加载标签。该方法将令牌作为参数。它还接受另外两个可选参数。如果您有兴趣,可以在文档中阅读有关它们的更多信息。
下面,我们传递第一个也是唯一一个必需的参数,并将返回值存储在 $variable 中。我们使用这个变量是因为cheerio 和Jquery$ 之间的相似性。如果需要,您可以使用不同的变量名称。
将以下代码添加到您的 app.js 文件中:
const $ = cheerio.load(markup);
console.log(pretty($.html()));
复制代码
如果您现在通过在终端上运行命令 app.js 来执行文件节点 app.js 中的代码,您应该能够在终端上看到标记。这是我在终端上看到的:
如何在 Cheerio 中选择元素
Cheerio 支持最常见的 CSS 选择器,例如类、id 和元素选择器。在下面的代码中,我们选择了类 fruits__mango 的元素,然后将所选元素记录到控制台。将以下代码添加到您的 app.js 文件中。
const mango = $(".fruits__mango");
console.log(mango.html()); // Mango
复制代码
如果您使用命令执行上面的代码行,它将在终端上生成 Mango 日志文本。 app.js``node app.js
如何获取 Cheerio 中元素的属性
您还可以选择一个元素并获取特定属性,例如类、id 或所有属性及其对应的值。
将以下代码添加到您的 app.js 文件中:
const apple = $(".fruits__apple");
console.log(apple.attr("class")); //fruits__apple
复制代码
以上代码将登录到 fruits__apple 终端。 fruits__apple 是被选元素的类。
如何在 Cheerio 中循环遍历元素列表
Cheerio 提供了 .each 方法来遍历多个选定的元素。
下面,我们选择所有元素并使用方法 li 循环遍历它们。 .each 我们在终端上记录每个列表项的文本内容。
将以下代码添加到您的 app.js 文件中。
const listItems = $("li");
console.log(listItems.length); // 2
listItems.each(function (idx, el) {
console.log($(el).text());
});
// Mango
// Apple
复制代码
上面的代码会记录2,也就是列表项的长度。代码执行后,文本 Mango 和将显示在终端上。苹果``app.js
如何在 Cheerio 中向标记追加或添加元素
Cheerio 提供了一种将元素附加或附加到标签的方法。
append 方法会将作为参数传递的元素附加到所选元素的最后一个子元素。另一方面,prepend 会将传递的元素添加到所选元素的第一个子元素之前。
将以下代码添加到您的 app.js 文件中:
const ul = $("ul");
ul.append("Banana");
ul.prepend("Pineapple");
console.log(pretty($.html()));
复制代码
在标记中添加和添加元素后,这是我在登录 $.html() 终端时看到的:
这些是 Cheerio 的基础知识,可帮助您开始网络抓取。要从 Wikipedia 抓取我们在本文开头描述的数据,请将以下代码复制并粘贴到 app.js 文件中:
// Loading the dependencies. We don't need pretty
// because we shall not log html to the terminal
const axios = require("axios");
const cheerio = require("cheerio");
const fs = require("fs");
// URL of the page we want to scrape
const url = "https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3";
// Async function which scrapes the data
async function scrapeData() {
try {
// Fetch HTML of the page we want to scrape
const { data } = await axios.get(url);
// Load HTML we fetched in the previous line
const $ = cheerio.load(data);
// Select all the list items in plainlist class
const listItems = $(".plainlist ul li");
// Stores data for all countries
const countries = [];
// Use .each method to loop through the li we selected
listItems.each((idx, el) => {
// Object holding data for each country/jurisdiction
const country = { name: "", iso3: "" };
// Select the text content of a and span elements
// Store the textcontent in the above object
country.name = $(el).children("a").text();
country.iso3 = $(el).children("span").text();
// Populate countries array with country data
countries.push(country);
});
// Logs countries array to the console
console.dir(countries);
// Write countries array in countries.json file
fs.writeFile("coutries.json", JSON.stringify(countries, null, 2), (err) => {
if (err) {
console.error(err);
return;
}
console.log("Successfully written data to file");
});
} catch (err) {
console.error(err);
}
}
// Invoke the above function
scrapeData();
复制代码
通过阅读代码,你明白发生了什么吗?如果没有,我现在将详细介绍。我还注释掉了每一行代码以帮助您理解。
在上面的代码中,我们需要app.js文件顶部的所有依赖,然后我们声明scrapeData函数。在函数内部,使用 axios。然后将我们需要抓取的页面的抓取 HTML 加载到 Cheerio 中。
国家列表及其对应的 iso3 代码嵌套在 div 元素的 class 中。普通名单。 li 元素被选中,然后我们使用 .each 方法循环遍历它们。每个国家的数据都被抓取并存储在一个数组中。
用命令node app.js运行上述代码后,将捕获的数据写入countrys.json文件并打印在终端上。这是我在终端上看到的部分内容:
结论
感谢您阅读本文!我们已经使用cheerio 进行了介绍。如果您想更深入地了解它的工作原理,可以前往 Cheerio 文档。