這篇參考手冊是對cheerio 官方文檔 的中文翻譯
cheerio是jquery核心功能的一個快速靈活而又簡潔的實現(xiàn)雷蹂,主要是為了用在服務器端需要對DOM進行操作的地方
簡介
讓你在服務器端和html愉快的玩耍
var cheerio = require('cheerio'),
$ = cheerio.load('<h2 class = "title">Hello world</h2>');
$('h2.title').text('Hello there!');
$('h2').addClass('welcome');
$.html();
//=> <h2 class = "title welcome">Hello there!</h2>
安裝
npm install cheerio
特點
熟悉的語法:cheerio實現(xiàn)了jQuery的一個子集掀淘,去掉了jQuery中所有與DOM不一致或者是用來填瀏覽器的坑的東西昌犹,重現(xiàn)了jQuery最美妙的API
快到?jīng)]朋友:cheerio使用了及其簡潔而又標準的DOM模型, 因此對文檔的轉(zhuǎn)換面褐,操作亿蒸,渲染都極其的高效∧掷玻基本的端到端測試顯示它的速度至少是JSDOM的8倍
極其靈活:cheerio使用了@FB55編寫的非常兼容的htmlparser2,因此它可以解析幾乎所有的HTML和XML
關于JSDOM
cheerio產(chǎn)生的原因是出于對JSDOM的失望辕坝,主要體現(xiàn)在以下三點:
JSDOM的解析規(guī)則太過于嚴格:JSDOM的解析器無法處理現(xiàn)在許多的流行網(wǎng)站的內(nèi)容
JSDOM太慢了:解析大的網(wǎng)站甚至可以產(chǎn)生可察覺的延遲
JSDOM太過于重量級:JSDOM的目標是提供與瀏覽器一樣的DOM環(huán)境窍奋,但是我們往往不需要這樣。我們需要的只是一種簡單酱畅,熟悉的方式來操作我們的HTML
什么時候你應該用JSDOM
cheerio并非萬能琳袄,當你需要一個瀏覽器一樣的環(huán)境時,你最好還是用JSDOM纺酸,尤其是你需要進行自動化的功能測試時
API
后面的例子中用到的HTML模板如下:
<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
<li class="pear">Pear</li>
</ul>
1. 解析html(load)
首先你需要先加載你的HTML窖逗。jQuery會自動完成這一步,因為jQuery操作的DOM是固定的餐蔬。但是在使用cheerio時我們要手動加載我們的HTML文檔
首選的方式如下:
var cheerio = require('cheerio'),
$ = cheerio.load('<ul id = "fruits">...</ul>');
其次碎紊,直接把HTML字符串作為上下文也是可以的:
$ = require('cheerio');
$('ul', '<ul id = "fruits">...</ul>');
或者把HTML字符串作為root
$ = require('cheerio');
$('li', 'ul', '<ul id = "fruits">...</ul>');
如果你需要自定義一些解析選項,你可以多傳遞一個對象給load方法:
$ = cheerio.load('<ul id = "fruits">...</ul>', {
ignoreWhitespace: true,
xmlMode: true
});
更多的解析選項可以參考domhandler和parser-options
2. 選擇器(selectors)
cheerio的選擇器幾乎和jQuery一模一樣樊诺,所以語法上十分相像
$( selector, [context], [root] )
selector在context的范圍內(nèi)搜索仗考,context的范圍又包含在root的范圍內(nèi)。selector和context可以是一個字符串啄骇,DOM元素痴鳄,DOM數(shù)組或者cheerio實例。root一般是一個HTML文檔字符串
選擇器是文檔遍歷和操作的起點缸夹。如同在jQuery中一樣痪寻,它是選擇元素節(jié)點最重要的方法螺句,但是在jQuery中選擇器建立在CSS選擇器標準庫上。cheerio的選擇器實現(xiàn)了大部分的方法
$('.apple', '#fruits').text()
//=> Apple
$('ul .pear').attr('class')
//=> pear
$('li[class=orange]').html()
//=> <li class = "orange">Orange</li>
3. 屬性操作(atrributes)
用來獲取和更改屬性的方法:
.attr(name, value)
這個方法用來獲取和設置屬性橡类。獲取第一個符合匹配的元素的屬性值蛇尚。如果某個屬性值被設置成null,那么該屬性會被移除顾画。你也可以把map和function作為參數(shù)傳遞進去取劫,就像在jQuery中一樣
$('ul').attr('id')
//=> fruits
$('.apple').attr('id', 'favorite').html()
//=> <li class = "apple" id = "favorite">Apple</li>
更多信息請查看 http://api.jquery.com/attr/
.removeAtrr(name)
移除名為name的屬性
$('.pear').removeAttr('class').html()
//=> <li>Pear</li>
.hasClass(className)
檢查元素是否含有此類名
$('.pear').hasClass('pear')
//=> true
$('apple').hasClass('fruit')
//=> false
$('li').hasClass('pear')
//=> true
.addClass(className)
添加類名到所有的匹配元素,可以用函數(shù)作為參數(shù)
$('.pear').addClass('fruit').html()
//=> <li class = "pear fruit">Pear</li>
$('.apple').addClass('fruit red').html()
//=> <li class = "apple fruit red">Apple</li>
.remoteClass([className])
移除一個或者多個(空格分隔)的類名研侣,如果className為空谱邪,則所有的類名都會被移除,可以傳遞函數(shù)作為參數(shù)
$('.pear').removeClass('pear').html()
//=> <li class = "">Pear</li>
$('.apple').addClass('red').removeClass().html()
//=> <li class = "">Apple</li>
遍歷
.find(selector)
在當前元素集合中選擇符合選擇器規(guī)則的元素集合
$('#fruits').find('li').length
//=> 3
.parent()
獲取元素集合第一個元素的父元素
$('.pear').parent().attr('id')
//=> fruits
.next()
選擇當前元素的下一個兄弟元素
$('.apple').next().hasClass('orange')
//=> true
.prev()
同.next()相反
.siblings()
獲取元素集合中第一個元素的所有兄弟元素庶诡,不包含它自己
$('.pear').siblings().length
//=> 2
.children( selector )
.each( function(index, element) )
遍歷函數(shù)返回false即可終止遍歷
var fruits = [];
$('li').each(function(i, elem) {
fruits[i] = $(this).text();
});
fruits.join(', ');
//=> Apple, Orange, Pear
.map( function(index, element) )
$('li').map(function(i, el) {
// this === el
return $(this).attr('class');
}).get().join(', ');
//=> apple, orange, pear
.filter( selector )
$('li').filter('.orange').attr('class');
//=> orange
.filter( function(index) )
$('li').filter(function(i, el) {
// this === el
return $(this).attr('class') === 'orange';
}).attr('class')
//=> orange
.first()
$('#fruits').children().first().text()
//=> Apple
.last()
$('#fruits').children().last().text()
//=> Pear
.eq( i )
縮小元素集合惦银,可以用負數(shù)表示倒數(shù)第 i 個元素被保留
$('li').eq(0).text()
//=> Apple
$('li').eq(-1).text()
//=> Pear
操作DOM
操作DOM結構的方法
.append( content, [content, ...] )
.prepend( content, [content, ...] )
.after( content, [content, ...] )
$('.apple').after('<li class = "plum">Plum</li>')
$.html()
//=> <ul id = "fruits">
// <li class = "apple">Apple</li>
// <li class = "plum">Plum</li>
// <li class = "orange">Orange</li>
// <li class = "pear">Pear</li>
// </ul>
.before( content, [content, ...] )
$('.apple').before('<li class = "plum">Plum</li>')
$.html()
//=> <ul id = "fruits">
// <li class = "plum">Plum</li>
// <li class = "apple">Apple</li>
// <li class = "orange">Orange</li>
// <li class = "pear">Pear</li>
// </ul>
.remove( [selector] )
$('.pear').remove()
$.html()
//=> <ul id = "fruits">
// <li class = "apple">Apple</li>
// <li class = "orange">Orange</li>
// </ul>
.replaceWith( content )
var plum = $('<li class = "plum">Plum</li>')
$('.pear').replaceWith(plum)
$.html()
//=> <ul id = "fruits">
// <li class = "apple">Apple</li>
// <li class = "orange">Orange</li>
// <li class = "plum">Plum</li>
// </ul>
.empty()
$('ul').empty()
$.html()
//=> <ul id = "fruits"></ul>
.html( [htmlString] )
$('.orange').html()
//=> Orange
$('#fruits').html('<li class = "mango">Mango</li>').html()
//=> <li class="mango">Mango</li>
.text( [textString] )
$('.orange').text()
//=> Orange
$('ul').text()
//=> Apple
// Orange
// Pear
解析和渲染
$.html()
//=> <ul id = "fruits">
// <li class = "apple">Apple</li>
// <li class = "orange">Orange</li>
// <li class = "pear">Pear</li>
// </ul>
輸出包含自己在內(nèi)的HTML(outer HTML)
$.html('.pear')
//=> <li class = "pear">Pear</li>
雜項
.toArray()
$('li').toArray()
//=> [ {...}, {...}, {...} ]
.clone()
var moreFruit = $('#fruits').clone()
常用工具
$.root()
$.root().append('<ul id="vegetables"></ul>').html();
//=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
$.contains( container, contained )