Cheerio: 快, 灵活, 轻, 特别为服务器端设计的 jQuery 核心实现
本文于 804 天之前发表,文中内容可能已经过时。
const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')
$('h2.title').text('Hello there!')
$('h2').addClass('welcome')
$.html()
//=> <html><head></head><body><h2 class="title welcome">Hello there!</h2></body></html>
安装
npm install cheerio
特性
❤ 熟悉的语法:
Cheerio 实现了 jQuery 核心 的一个子集。Cheerio 从 jQuery 库中,删除了所有 DOM 和浏览器不一致的残骸,揭示了它真正华丽的 API。
ϟ 非常快:
Cheerio 使用非常简单,一致的 DOM 模型。因此,解析,操纵和渲染非常有效。初步的端到端基准测试表明,cheerio 是8x快于 JSDOM 。
❁ 非常灵活:
Cheerio wraps around parse5 parser and can optionally use @FB55’s forgiving htmlparser2。Cheerio 几乎可以解析,任何 HTML 或 XML 文档。
Cheerio 不是 Web 浏览器
Cheerio 解析(html)标记,并提供用于遍历/操纵,结果数据结构的 API。它不会像 Web 浏览器那样解释结果。具体来说,并不会生成可视化渲染,应用 CSS,加载外部资源或执行 JavaScript。如果您的用例,需要任何此功能,您应该考虑像其他项目:PhantomJS 或 JSDom。
API
我们将会用到的代码示例:
<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
<li class="pear">Pear</li>
</ul>
这里的 HTML 标记,是我们所有 API 示例的。
加载
首先,您需要加载 HTML。jQuery 中的这一步是隐含的,因为 jQuery 在一个烤着的 DOM 上运行的。而 Cheerio,我们是需要传递 HTML 文档给它。
这是首选方法:
const cheerio = require('cheerio');
const $ = cheerio.load('<ul id="fruits">...</ul>');
或者,您也可以通过,将字符串作为上下文传递,来加载 HTML:
const $ = require('cheerio');
$('ul', '<ul id="fruits">...</ul>');
或者直接选择li
元素:
const $ = require('cheerio');
$('li', 'ul', '<ul id="fruits">...</ul>');
.load()
还可以传递一个额外的对象,如果您需要修改任何默认解析选项的话:
const $ = cheerio.load('<ul id="fruits">...</ul>', {
xml: {
normalizeWhitespace: true,
}
});
这些解析选项,直接来自htmlparser2,因此,任何htmlparser2
可用的选项,在 cheerio 中也有效。默认选项是:
{
withDomLvl1: true,
normalizeWhitespace: false,
xmlMode: true,
decodeEntities: true
}
有关选项及其效果的完整列表,请参阅这里和htmlparser2 的选项。
Some users may wish to parse markup with the htmlparser2
library, and
traverse/manipulate the resulting structure with Cheerio. This may be the case
for those upgrading from pre-1.0 releases of Cheerio (which relied onhtmlparser2
), for those dealing with invalid markup (because htmlparser2
is
more forgiving), or for those operating in performance-critical situations
(because htmlparser2
may be faster in some cases). Note that “more forgiving”
means htmlparser2
has error-correcting mechanisms that aren’t always a match
for the standards observed by web browsers. This behavior may be useful when
parsing non-HTML content.
To support these cases, load
also accepts a htmlparser2
-compatible data
structure as its first argument. Users may install htmlparser2
, use it to
parse input, and pass the result to load
:
// Usage as of htmlparser2 version 3:
const htmlparser2 = require('htmlparser2');
const dom = htmlparser2.parseDOM(document, options);
const $ = cheerio.load(dom);
选择器
Cheerio 的选择器实现,几乎与 jQuery 相同,因此 API 非常相似。
$( selector, [context], [root] )
selector
,会搜索context
范围,而该范围又是从root
范围搜索而来。selector
和context
可以是字符串表达式,DOM 元素,DOM 元素数组或 cheerio 对象。root
通常是 HTML 文档字符串。
此选择器方法是遍历和操纵文档的起点。像 jQuery 一样,它是在文档中,选择元素的主要方法,但与 jQuery 不同,我们是构建在 CSSSelect 库之上的,CSSSelect 实现了大多数的 Sizzle 选择器。
$('.apple', '#fruits').text()
//=> Apple
$('ul .pear').attr('class')
//=> pear
$('li[class=orange]').html()
//=> Orange
XML Namespaces
您可以选择 XML 命名空间,但是遵循 CSS 规范,冒号(:
)需要进行转义,才能使选择器有效。
$('[xml\\:id="main"');
渲染
When you’re ready to render the document, you can call the html
method on the “root” selection:
$.root().html()
//=> <html>
// <head></head>
// <body>
// <ul id="fruits">
// <li class="apple">Apple</li>
// <li class="orange">Orange</li>
// <li class="pear">Pear</li>
// </ul>
// </body>
// </html>
If you want to render the outerHTML
of a selection, you can use the html
utility functon:
cheerio.html($('.pear'))
//=> <li class="pear">Pear</li>
By default, html
will leave some tags open. Sometimes you may instead want to render a valid XML document. For example, you might parse the following XML snippet:
const $ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');
… and later want to render to XML. To do this, you can use the ‘xml’ utility function:
$.xml()
//=> <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>
You may also render the text content of a Cheerio object using the text
static method:
const $ = cheerio.load('This is <em>content</em>.')
cheerio.text($('body'))
//=> This is content.
插件
一旦加载文档后,您可以扩展原型,或等效fn
属性,使用自定义插件方法:
const $ = cheerio.load('<html><body>Hello, <b>world</b>!</body></html>');
$.prototype.logHtml = function() {
console.log(this.html());
};
$('body').logHtml(); // logs "Hello, <b>world</b>!" to the console
“DOM Node” 对象
Cheerio 所制造的对象,与基于浏览器的 DOM 节点有许多相似之处。所以,您可以期望它们定义了以下属性:
tagName
parentNode
previousSibling
nextSibling
nodeValue
firstChild
childNodes
lastChild
Screencasts
这个视频教程是 Nettut 的“如何使用 Node.js 和 jQuery 抓取网页”的后续内容,使用 cheerio 而不是 JSDOM + jQuery。这个视频展示了使用 cheerio 是多么容易,以及 cheerio 比 JSDOM + jQuery 快多少。
测试
要运行测试套件,请下载存储库,然后在 cheerio 目录中,运行:
make setup
make test
这将下载开发包,并运行测试套件。
评论系统未开启,无法评论!