Cheerio 教程展示了如何使用 Cheerio 模块在 JavaScript 中进行网页抓取。 Cheerio 实现了为服务器设计的 jQuery 的核心。
Cheerio
Cheerio 是专门为服务器设计的核心 jQuery 的快速,灵活和精益实现。
在本教程中,我们从本地 Web 服务器上抓取 HTML。 对于本地 Web 服务器,我们使用local-web-server
。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Home page</title>
<style>
.fpar {
font-family: Georgia;
}
</style>
</head>
<body>
<main>
<h1>My website</h1>
<p class="fpar">
I am a JavaScript programmer.
</p>
<p>
My hobbies are:
</p>
<ul>
<li>Swimming</li>
<li>Tai Chi</li>
<li>Running</li>
<li>Web development</li>
<li>Reading</li>
<li>Music</li>
</ul>
</main>
</body>
</html>
我们将使用此 HTML 文件。
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 和其他模块
我们安装了cheerio
模块和两个附加模块。
$ nodejs -v
v9.11.2
我们使用 Node 版本 9.11.2。
$ sudo npm i cheerio
$ sudo npm i request
$ sudo npm i -g local-web-server
我们安装cheerio
,request
和local-web-server
。
$ ws
Serving at http://t400:8000, http://127.0.0.1:8000, http://192.168.0.3:8000
在项目目录中,我们有index.html
文件,我们启动了本地 Web 服务器。 它会自动在三个不同的位置提供index.html
文件。
Cheerio 标题
在第一个示例中,我们获得了文档的标题。
get_title.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let title = $('title');
console.log(title.text());
});
该示例打印 HTML 文档的标题。
const cheerio = require('cheerio');
const request = require('request');
我们包括cheerio
和request
模块。 使用cheerio
,我们可以进行网页抓取。 使用request
,我们创建 GET 请求。
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
我们向本地 Web 服务器提供的 localhost 创建 GET 请求。 该资源在body
参数中可用。
let $ = cheerio.load(body);
首先,我们加载 HTML 文档。 为了模仿 jQuery,我们使用$
变量。
let title = $('title');
选择器返回title
标签。
console.log(title.text());
使用text()
方法,我们获得title
标签的文本。
$ node get_title.js
Home page
该示例打印文档的标题。
Cheerio 获取父元素
使用parent()
检索父元素。
get_parent.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let h1El = $('h1');
let parentEl = h1El.parent();
console.log(parentEl.get(0).tagName)
});
我们得到h1
元素的父元素。
$ node get_parent.js
main
h1
的父元素是main
。
Cheerio 第一个&最后一个元素
cheerio
对象的第一个元素可以使用first()
找到,最后一个元素可以使用last()
找到。
first_last.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let main = $('main');
let fel = main.children().first();
let lel = main.children().last();
console.log(fel.get(0).tagName);
console.log(lel.get(0).tagName);
});
该示例打印main
标签的第一个和最后一个元素。
let main = $('main');
我们选择main
标签。
let fel = main.children().first();
let lel = main.children().last();
我们从main
子级中获得第一个和最后一个元素。
console.log(fel.get(0).tagName);
console.log(lel.get(0).tagName);
我们找出标签名称。
$ node first_last.js
h1
ul
main
的第一个标签是h1
,最后一个标签是ul
。
Cheerio 添加元素
append()
方法在指定标签的末尾添加一个新元素。
add_element.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let ulEl = $('ul');
ulEl.append('<li>Travel</li>');
let lis = $('ul').html();
let items = lis.split('\n');
items.forEach((e) => {
if (e) {
console.log(e.replace(/(\s+)/g, ''));
}
});
});
在示例中,我们向ul
元素添加了一个新列表项,并将其打印到控制台。
ulEl.append('<li>Travel</li>');
我们增加了一个新的爱好。
let lis = $('ul').html();
我们得到ul
标签的 HTML。
let items = lis.split('\n');
items.forEach((e) => {
if (e) {
console.log(e.replace(/(\s+)/g, ''));
}
});
我们去除空格。 元素的文本数据包含大量空间。
$ node add_element.js
<li>Swimming</li>
<li>TaiChi</li>
<li>Running</li>
<li>Webdevelopment</li>
<li>Reading</li>
<li>Music</li>
<li>Travel</li>
在列表的末尾附加了一个新的旅行爱好。
Cheerio 元素后插入
使用after()
,我们可以在标签后插入元素。
insert_after.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
$('main').after('<footer>This is a footer</footer>')
console.log($.html());
});
在示例中,我们在main
元素之后插入一个footer
元素。
Cheerio 在元素上循环
使用each()
,我们可以循环遍历元素。
loop_elements.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let hobbies = [];
$('li').each(function (i, e) {
hobbies[i] = $(this).text();
});
console.log(hobbies);
});
该示例循环访问ul
的li
标签,并打印数组中元素的文本。
$ node loop_elements.js
[ 'Swimming',
'Tai Chi',
'Running',
'Web development',
'Reading',
'Music' ]
这是输出。
Cheerio 获取元素属性
可以使用attr()
函数检索属性。
attributes.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let fpEl = $('h1 + p');
let attrs = fpEl.attr();
console.log(attrs);
});
在示例中,我们获得了h1
的直接同级段落的属性。
$ node attributes.js
{ class: 'fpar' }
该段包含fpar
类。
Cheerio 过滤器
我们可以使用filter()
在元素上应用过滤器。
filtering.js
const cheerio = require('cheerio');
const request = require('request');
request({
method: 'GET',
url: 'http://localhost:8000'
}, (err, res, body) => {
if (err) return console.error(err);
let $ = cheerio.load(body);
let allEls = $('*');
let filteredEls = allEls.filter(function (i, el) {
// this === el
return $(this).children().length > 3;
});
let items = filteredEls.get();
items.forEach(e => {
console.log(e.name);
});
});
在示例中,我们找到了包含三个以上子元素的文档的所有元素。
let allEls = $('*');
*
选择器选择所有元素。
let filteredEls = allEls.filter(function (i, el) {
// this === el
return $(this).children().length > 3;
});
在检索到的元素上,我们应用过滤器。 仅当元素包含三个以上的子元素时,该元素才包含在过滤列表中。
let items = filteredEls.get();
items.forEach(e => {
console.log(e.name);
});
我们遍历过滤后的列表并打印元素的名称。
$ node filtering.js
head
main
ul
head
,main
和ul
元素包含三个以上的子代。 不包含body
,因为它仅包含一个直属子代。
在本教程中,我们使用 Cheerio 库在 JavaScript 中完成了 Web 抓取。
您可能也对以下相关教程感兴趣: JQuery 教程, Moment.js 教程,从 JavaScript 中的 URL 读取 JSON , JavaScript 贪食蛇教程 , Node Sass 教程, Lodash 教程。