Cheerio 教程
最后修改于 2023 年 10 月 18 日
在本文中,我们将展示如何使用 Cheerio 模块在 JavaScript 中进行 Web 抓取。Cheerio 实现了专为服务器设计的 jQuery 核心功能。
Cheerio
Cheerio 是一个快速、灵活且精简的 jQuery 核心实现,专为服务器设计。
它解析标记并提供一个 API,用于遍历/操作生成的数据结构。我
Cheerio 选择器
在 Cherrion 中,我们使用选择器来选择 HTML 文档的标签。选择器语法是从 jQuery 借用的。
以下是可用选择器的部分列表
- $("*") — 选择所有元素
- $("#first") — 选择
id="first"
的元素 - $(".intro") — 选择所有
class="intro"
的元素 - $("div") — 选择所有
<div>
元素 - $("h2, div, p") — 选择所有
<h2>, <div>, <p>
元素 - $("li:first") — 选择第一个
<li>
元素 - $("li:last") — 选择最后一个
<li>
元素 - $("li:even") — 选择所有偶数
<li>
元素 - $("li:odd") — 选择所有奇数
<li>
元素 - $(":empty") — 选择所有空元素
- $(":focus") — 选择当前具有焦点的元素
安装 Cheerio 和 Node Fetch
我们安装 cheerio 和 node-fetch 模块。Node Fetch 是一个用于在 JavaScript 中创建请求的包。
$ nodejs -v v18.2.0
我们使用 Node 版本 18.2.0。
$ npm i cheerio $ npm i node-fetch
我们安装 cheerio
和 node-fetch
包。
Cheerio 标题
在第一个示例中,我们获取文档的标题。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let title = $('title'); console.log(title.text());
该示例检索 HTML 文档的标题。
import fetch from 'node-fetch'; import { load } from 'cheerio';
我们包含 cheerio
和 node-fetch
模块。
const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text();
我们向网页创建 GET 请求。我们获取响应对象,并从响应对象中获取其主体。
let $ = cheerio.load(body);
首先,我们加载 HTML 文档。为了模仿 jQuery,我们使用 $
变量。
let title = $('title');
选择器返回 title
标签。
console.log(title.text());
使用 text
方法,我们获取 title
标签的文本。
$ node main.js My html page
该示例打印文档的标题。
Cheerio 获取父元素
父元素通过 parent
检索。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let title = $('title'); let parentEl = title.parent(); console.log(parentEl.get(0).tagName);
我们获取 title
元素的父元素。
$ node main.js head
Cheerio 第一个和最后一个元素
可以使用 first
找到 cheerio 对象的第一个元素,使用 last
找到最后一个元素。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let head = $('head'); let fel = head.children().first(); let lel = head.children().last(); console.log(fel.get(0).tagName); console.log(lel.get(0).tagName);
该示例打印 main
标签的第一个和最后一个元素。
let head = $('head');
我们选择 head
标签。
let fel = head.children().first(); let lel = head.children().last();
我们从 main
子元素中获取第一个和最后一个元素。
console.log(fel.get(0).tagName); console.log(lel.get(0).tagName);
我们找出标签名称。
$ node main.js meta title
Cheerio 添加元素
append
方法在指定标签的末尾添加一个新元素。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let bodyEl = $('body'); bodyEl.append('<p>An old falcon</p>'); let content = $('body').html(); let items = content.split('\n'); items.forEach((e) => { console.log(e.trim()); });
在该示例中,我们将一个段落添加到 body 标签并将其打印到控制台。
bodyEl.append('<p>An old falcon</p>');
我们追加一个新段落。
let content = $('body').html();
我们获取 body
标签的 HTML。
let items = content.split('\n'); items.forEach((e) => { console.log(e.trim()); });
我们打印内容并删除一些空白。
Cheerio 在元素之后插入
使用 after
,我们可以在一个标签之后插入一个元素。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://example.com' const response = await fetch(url); const body = await response.text(); let $ = load(body); $('div').after('<footer>This is a footer</footer>') console.log($.html());
在该示例中,我们在 div
元素之后插入一个 footer
元素。
Cheerio 循环遍历元素
使用 each
,我们可以循环遍历元素。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me/countries.html' const response = await fetch(url); const body = await response.text(); let $ = load(body); $('tr').each((_, e) => { let row = $(e).text().replace(/(\s+)/g, ' '); console.log(`${row}`); });
该示例循环遍历 tr
标签并打印元素的文本。
$ node main.js Id Name Population 1 China 1382050000 2 India 1313210000 3 USA 324666000 4 Indonesia 260581000 5 Brazil 207221000 6 Pakistan 196626000 ...
Cherio 获取第 n 个元素
使用 nth-child
伪类,我们可以选择某个标签的第 n 个元素。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me/countries.html' const response = await fetch(url); const body = await response.text(); let $ = load(body); let el9 = $('tr:nth-child(9)'); let res = el9.text().trim(); console.log(res.replace(/(\s+)/g, ' '));
在该示例中,我们选择世界人口最多的国家列表中第九个元素。
$ node main.js 9 Russia 146838000
Cheerio 获取元素属性
可以使用 attr
函数检索属性。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let lnEl = $('link'); let attrs = lnEl.attr(); console.log(attrs.rel); console.log(attrs.href);
在该示例中,我们获取 link
标签的 rel
和 href
属性。
$ node main.js stylesheet format.css
Cheerio 过滤元素
我们可以使用 filter
来对元素应用过滤器。
import fetch from 'node-fetch'; import { load } from 'cheerio'; const url = 'http://webcode.me'; const response = await fetch(url); const body = await response.text(); let $ = load(body); let all = $('*'); let res = all.filter((i, e) => { return $(e).children().length === 2; }); let items = res.get(); items.forEach(e => { console.log(e.name); });
在该示例中,我们找出文档中包含两个子元素的所有元素。
let all = $('*');
*
选择器选择所有元素。
let res = all.filter((i, e) => { return $(e).children().length === 2; });
在检索到的元素上,我们应用一个过滤器。仅当元素包含恰好两个子元素时,才将其包含在过滤列表中。
let items = res.get(); items.forEach(e => { console.log(e.name); });
我们遍历过滤列表并打印元素的名称。
$ node main.js html body
来源
在本文中,我们使用 Cheerio 库在 JavaScript 中进行了 Web 抓取。