多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Cheerio 教程 > 原文: [http://zetcode.com/javascript/cheerio/](http://zetcode.com/javascript/cheerio/) Cheerio 教程展示了如何使用 Cheerio 模块在 JavaScript 中进行网页抓取。 Cheerio 实现了为服务器设计的 jQuery 的核心。 ## Cheerio Cheerio 是专门为服务器设计的核心 jQuery 的快速,灵活和精益实现。 在本教程中,我们从本地 Web 服务器上抓取 HTML。 对于本地 Web 服务器,我们使用`local-web-server`。 `index.html` ```js <!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`模块和两个附加模块。 ```js $ nodejs -v v9.11.2 ``` 我们使用 Node 版本 9.11.2。 ```js $ sudo npm i cheerio $ sudo npm i request $ sudo npm i -g local-web-server ``` 我们安装`cheerio`,`request`和`local-web-server`。 ```js $ 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` ```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 文档的标题。 ```js const cheerio = require('cheerio'); const request = require('request'); ``` 我们包括`cheerio`和`request`模块。 使用`cheerio`,我们可以进行网页抓取。 使用`request`,我们创建 GET 请求。 ```js request({ method: 'GET', url: 'http://localhost:8000' }, (err, res, body) => { ``` 我们向本地 Web 服务器提供的 localhost 创建 GET 请求。 该资源在`body`参数中可用。 ```js let $ = cheerio.load(body); ``` 首先,我们加载 HTML 文档。 为了模仿 jQuery,我们使用`$`变量。 ```js let title = $('title'); ``` 选择器返回`title`标签。 ```js console.log(title.text()); ``` 使用`text()`方法,我们获得`title`标签的文本。 ```js $ node get_title.js Home page ``` 该示例打印文档的标题。 ## Cheerio 获取父元素 使用`parent()`检索父元素。 `get_parent.js` ```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`元素的父元素。 ```js $ node get_parent.js main ``` `h1`的父元素是`main`。 ## Cheerio 第一个&最后一个元素 `cheerio`对象的第一个元素可以使用`first()`找到,最后一个元素可以使用`last()`找到。 `first_last.js` ```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`标签的第一个和最后一个元素。 ```js let main = $('main'); ``` 我们选择`main`标签。 ```js let fel = main.children().first(); let lel = main.children().last(); ``` 我们从`main`子级中获得第一个和最后一个元素。 ```js console.log(fel.get(0).tagName); console.log(lel.get(0).tagName); ``` 我们找出标签名称。 ```js $ node first_last.js h1 ul ``` `main`的第一个标签是`h1`,最后一个标签是`ul`。 ## Cheerio 添加元素 `append()`方法在指定标签的末尾添加一个新元素。 `add_element.js` ```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`元素添加了一个新列表项,并将其打印到控制台。 ```js ulEl.append('<li>Travel</li>'); ``` 我们增加了一个新的爱好。 ```js let lis = $('ul').html(); ``` 我们得到`ul`标签的 HTML。 ```js let items = lis.split('\n'); items.forEach((e) => { if (e) { console.log(e.replace(/(\s+)/g, '')); } }); ``` 我们去除空格。 元素的文本数据包含大量空间。 ```js $ 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` ```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` ```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`标签,并打印数组中元素的文本。 ```js $ node loop_elements.js [ 'Swimming', 'Tai Chi', 'Running', 'Web development', 'Reading', 'Music' ] ``` 这是输出。 ## Cheerio 获取元素属性 可以使用`attr()`函数检索属性。 `attributes.js` ```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`的直接同级段落的属性。 ```js $ node attributes.js { class: 'fpar' } ``` 该段包含`fpar`类。 ## Cheerio 过滤器 我们可以使用`filter()`在元素上应用过滤器。 `filtering.js` ```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); }); }); ``` 在示例中,我们找到了包含三个以上子元素的文档的所有元素。 ```js let allEls = $('*'); ``` `*`选择器选择所有元素。 ```js let filteredEls = allEls.filter(function (i, el) { // this === el return $(this).children().length > 3; }); ``` 在检索到的元素上,我们应用过滤器。 仅当元素包含三个以上的子元素时,该元素才包含在过滤列表中。 ```js let items = filteredEls.get(); items.forEach(e => { console.log(e.name); }); ``` 我们遍历过滤后的列表并打印元素的名称。 ```js $ node filtering.js head main ul ``` `head`,`main`和`ul`元素包含三个以上的子代。 不包含`body`,因为它仅包含一个直属子代。 在本教程中,我们使用 Cheerio 库在 JavaScript 中完成了 Web 抓取。 您可能也对以下相关教程感兴趣: [JQuery 教程](/web/jquery/), [Moment.js 教程](/javascript/momentjs/),[从 JavaScript 中的 URL 读取 JSON](/articles/javascriptjsonurl/) , [JavaScript 贪食蛇教程](/javascript/snake/) , [Node Sass 教程](/javascript/nodesass/), [Lodash 教程](/javascript/lodash/)。