[轉(zhuǎn)載]通讀cheerio API

轉(zhuǎn)載自http://cnodejs.org/topic/5203a71844e76d216a727d2e 焰枢,略加美化拱雏,以下正文。

所謂工欲善其事悬包,必先利其器,所以通讀了cheerio的API馍乙,順便翻譯了一遍,有些地方因為知道的比較少垫释,不知道什么意思丝格,保留了英文,希望各位不吝告訴我棵譬,然后一起把這個翻譯完成显蝌。

cheerio

為服務(wù)器特別定制的,快速、靈活曼尊、實施的jQuery核心實現(xiàn).

Introduction

將HTML告訴你的服務(wù)器

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>

Installationnpm install cheerio

Features

? 相似的語法:Cheerio 包括了 jQuery 核心的子集酬诀。Cheerio 從jQuery庫中去除了所有 DOM不一致性和瀏覽器尷尬的部分,揭示了它真正優(yōu)雅的API骆撇。
? 閃電般的塊:Cheerio 工作在一個非常簡單瞒御,一致的DOM模型之上。解析神郊,操作肴裙,呈送都變得難以置信的高效∮咳椋基礎(chǔ)的端到端的基準(zhǔn)測試顯示Cheerio 大約比JSDOM快八倍(8x)蜻懦。
? 巨靈活: Cheerio 封裝了兼容的htmlparser。Cheerio 幾乎能夠解析任何的 HTML 和 XML document夕晓。

What about JSDOM

我寫cheerio 是因為我發(fā)現(xiàn)我自己對JSDOM越來越沮喪宛乃。對于我來說,總是會一次又一次的碰上幾個難點蒸辆。
JSDOM內(nèi)建的解析太過于嚴(yán)格: JSDOM附帶的HTML解析不能處理很多當(dāng)下的大眾的網(wǎng)站征炼。

JSDOM太慢:用JSDOM解析大型網(wǎng)站存在可見的延遲。

JSDOM太累贅:JSDOM的目標(biāo)是提供一個我們在瀏覽器里面看到的相同的 DOM 環(huán)境吁朦。我從沒有真的需要所有這些東西柒室,我只是想要一個簡單的,相似的方法去處理HTML逗宜。

When I would use JSDOMCheerio

不會解決你的所有問題雄右。我人會使用JSDOM如果我需要用一個在服務(wù)器上的瀏覽器環(huán)境,特別是如果我想要自動化一些功能測試纺讲。

API

我們將用到的標(biāo)記示例

<ul id=“fruits”>
  <li class=“apple”>Apple</li>
  <li class=“orange”>Orange</li>
  <li class=“pear”>Pear</li>
</ul>

這是我們將會在所有的API例子中用到的HTML標(biāo)記

Loading

首先你需要加載HTML擂仍。這一步對jQuery來說是必須的,since jQuery operates on the one, baked-in DOM熬甚。通過Cheerio,我們需要把HTML document 傳進(jìn)去逢渔。
這是首選:

var cheerio = require('cheerio'), $ = cheerio.load('<ul id="fruits">...</ul>');

或者通過傳遞字符串作為內(nèi)容來加載HTML:

$ = require('cheerio');$('ul', '<ul id="fruits">...</ul>');

Or as the root:

$ = require('cheerio');$('li', 'ul', '<ul id="fruits">...</ul>');

你也可以傳遞一個額外的對象給.load()如果你需要更改任何的默認(rèn)解析選項的話:

$ = cheerio.load('<ul id="fruits">...</ul>', { ignoreWhitespace: true, xmlMode: true});

這些解析選項都是直接來自htmlparser ,因此任何在htmlparser里有效的選項在Chreeio里也是行得通的乡括。默認(rèn)的選項如下:

{ ignoreWhitespace: false, xmlMode: false, lowerCaseTags: false}

想看選項清單和它們都效果肃廓,看DomHandlerParser-options

Selectors

Cheerio的選擇器用起來幾乎和jQuery一樣,所以API也很相似诲泌。

$(selectior,[context],[root])

選擇器在 Context 范圍內(nèi)搜索盲赊,Context又在Root范圍內(nèi)搜索。selector 和context可是是一個字符串表達(dá)式敷扫,DOM元素哀蘑,和DOM元素的數(shù)組,或者chreeio對象。root 是通常是HTML 文檔字符串绘迁。

$('.apple', '#fruits').text()
//=> Apple$('ul .pear').attr('class')
//=> pear$('li[class=orange]').html()
//=> <li class="orange">Orange</li>

Attributes獲得和修改屬性

.attr(name,value)

獲得和修改屬性合溺。在匹配的元素中只能獲得第一元素的屬性。如果設(shè)置一個屬性的值為null缀台,則移除這個屬性棠赛。你也可以傳遞一對鍵值,或者一個函數(shù)将硝。

$('ul').attr('id')
//=> fruits
$('.apple').attr('id', 'favorite').html()
//=> <li class="apple" id="favorite">Apple</li>

更多信息請看這里

.value([value])

獲得和修改input,select,textarea的value.注意: 對于傳遞鍵值和函數(shù)的支持還沒有被加進(jìn)去恭朗。

$('input[type="text"]').val()
// => input_text
$('input[type="text"]').val('test').html()
// => <input type="text" value="test"/>
.removeAttr(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)

增加class(es)給所有匹配的elements.也可以傳函數(shù)。

$('.pear').addClass('fruit').html()
//=> <li class="pear fruit">Pear</li>
$('.apple').addClass('fruit red').html()
//=> <li class="apple fruit red">Apple</li>

更多信息看這里

.removeClass([className])

從選擇的elements里去除一個或多個有空格分開的class依疼。如果className 沒有定義痰腮,所有的classes將會被去除,也可以傳函數(shù)律罢。

$('.pear').removeClass('pear').html()
//=> <li class="">Pear</li>
$('.apple').addClass('red').removeClass().html()
//=> <li class="">Apple</li>

更多信息看這里

.is.(selector)
.is(function(index))

有任何元素匹配selector就返回true膀值。如果使用判定函數(shù),判定函數(shù)在選中的元素中執(zhí)行误辑,所以this指向當(dāng)前的元素沧踏。

Traversing

.find(selector)

獲得一個在匹配的元素中由選擇器濾過的后代。

$('#fruits').find('li').length
//=> 3
.parent([selector])

獲得每個匹配元素的parent,可選擇性的通過selector篩選巾钉。

$('.pear').parent().attr('id')
//=> fruits
.parents([selector])

獲得通過選擇器篩選匹配的元素的parent集合翘狱。

$('.orange').parents().length
// => 2
$('.orange').parents('#fruits').length
// => 1
.closest([selector])

對于每個集合內(nèi)的元素,通過測試這個元素和DOM層級關(guān)系上的祖先元素砰苍,獲得第一個匹配的元素

$('.orange').closest()
// => []
$('.orange').closest('.apple')
// => []
$('.orange').closest('li')
// => [<li class="orange">Orange</li>]
$('.orange').closest('#fruits')
// => [<ul id="fruits"> ... </ul>]
.next()

獲得第一個本元素之后的同級元素

$('.apple').next().hasClass('orange')
//=> true
.nextAll()

獲得本元素之后的所有同級元素

$('.apple').nextAll()
//=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>]
.prev()

獲得本元素之前的第一個同級元素

$('.orange').prev().hasClass('apple')
//=> true
.preAll()

獲得本元素前的所有同級元素

$('.pear').prevAll()
//=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>]
.slice(start,[end])

獲得選定范圍內(nèi)的元素

$('li').slice(1).eq(0).text()
//=> 'Orange'
$('li').slice(1, 2).length
//=> 1
.siblings(selector)

獲得被選擇的同級元素潦匈,除去自己??

$('.pear').siblings().length
//=> 2
$('.pear').siblings('.orange').length
//=> 1
.children(selector)

獲被選擇元素的子元素

$('#fruits').children().length
//=> 3
$('#fruits').children('.pear').text()
//=> Pear
.each(function(index,element))

迭代一個cheerio對象,為每個匹配元素執(zhí)行一個函數(shù)赚导。
When the callback is fired, the function is fired in the context of the DOM element, so this refers to the current element, which is equivalent to the function parameter element.
要提早跳出循環(huán)茬缩,返回false.

var fruits = [];
$('li').each(function(i, elem) {
  fruits[i] = $(this).text();
});
fruits.join(', ');
//=> Apple, Orange, Pear
.map(function(index,element))

迭代一個cheerio對象,為每個匹配元素執(zhí)行一個函數(shù)吼旧。Map會返回一個迭代結(jié)果的數(shù)組凰锡。
the function is fired in the context of the DOM element, so this refers to the current element, which is equivalent to the function parameter element

$('li').map(function(i, el) {
  // this === el
  return $(this).attr('class');
}).join(', ');
//=> apple, orange, pear
.filter(selector)
.filter(function(index))

迭代一個cheerio對象,濾出匹配選擇器或者是傳進(jìn)去的函數(shù)的元素圈暗。如果使用函數(shù)方法掂为,這個函數(shù)在被選擇的元素中執(zhí)行,所以this指向的手勢當(dāng)前元素员串。
Selector:

$('li').filter('.orange').attr('class');
//=> orange

Function:

$('li').filter(function(i, el) {
  // this === el
  return $(this).attr('class') === 'orange';
}).attr('class')
//=> orange
.first()

會選擇chreeio對象的第一個元素

$('#fruits').children().first().text()
//=> Apple
.last()

會選擇chreeio對象的最后一個元素

$('#fruits').children().last().text()
//=> Pear
.eq(i)

通過索引篩選匹配的元素菩掏。使用.eq(-i)就從最后一個元素向前數(shù)。

$('li').eq(0).text()
//=> Apple
$('li').eq(-1).text()
//=> Pear

Manipulation

改變DOM結(jié)構(gòu)的方法

.append(content,[content…])

在每個元素最后插入一個子元素

$('ul').append('<li class="plum">Plum</li>')
$.html()
//=> <ul id="fruits">
// <li class="apple">Apple</li>
// <li class="orange">Orange</li>
// <li class="pear">Pear</li>
// <li class="plum">Plum</li>
// </ul>
.prepend(content,[content,…])

在每個元素最前插入一個子元素

$('ul').prepend('<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>
.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] )

從DOM中去除匹配的元素和它們的子元素昵济。選擇器用來篩選要刪除的元素。

$('.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] )

獲得元素的HTML字符串访忿。如果htmlString有內(nèi)容的話瞧栗,將會替代原來的HTML

$('.orange').html()
//=> Orange
$('#fruits').html('<li class="mango">Mango</li>').html()
//=> <li class="mango">Mango</li>
.text( [textString] )

獲得元素的text內(nèi)容,包括子元素聂儒。如果textString被指定的話官册,每個元素的text內(nèi)容都會被替換批什。

$('.orange').text()
//=> Orange$('ul').text()
//=> Apple
// Orange
// Pear

Rendering

如果你想呈送document,你能使用html多效用函數(shù)殴边。

$.html()
//=> <ul id="fruits">
// <li class="apple">Apple</li>
// <li class="orange">Orange</li>
// <li class="pear">Pear</li>
// </ul>

如果你想呈送outerHTML,你可以使用 $.html(selector)

$.html('.pear')
//=> <li class="pear">Pear</li>

默認(rèn)的,html會讓一些標(biāo)簽保持開標(biāo)簽的狀態(tài).有時候你想呈現(xiàn)一個有效的XML文檔.例如下面這個:

$ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');

然后為了呈現(xiàn)這個XML,你需要使用xml
這個函數(shù):

$.xml()
//=> <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>

Miscellaneous

不屬于其它地方的DOM 元素方法

.toArray()

取得所有的在DOM元素,轉(zhuǎn)化為數(shù)組

$('li').toArray()
//=> [ {...}, {...}, {...} ]
.clone()

克隆cheerio對象

var moreFruit = $('#fruits').clone()

Utilities

$.root

有時候你想找到最上層的root元素,那么$.root()就能獲得:

$.root().append('<ul id="vegetables"></ul>').html();
//=> <ul id="fruits">...</ul><ul id="vegetables"></ul>
$.contains( container, contained )

查看cotained元素是否是container元素的子元素

$.parseHTML( data [, context ] [, keepScripts ] )

將字符串解析為DOM節(jié)點數(shù)組珍语。context參數(shù)對chreeio沒有意義锤岸,但是用來維護(hù)APi的兼容性。

Screencasts

http://vimeo.com/31950192
這個視頻教程是follow-up Nettut的"How to Scrape Web Pages with Node.js and jQuery"板乙,用 cheerio而不是JSDOM+JQuery. 這個視頻就是展示chreeio多牛B是偷,多快的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末募逞,一起剝皮案震驚了整個濱河市蛋铆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌放接,老刑警劉巖刺啦,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纠脾,居然都是意外死亡玛瘸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門乳乌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捧韵,“玉大人,你說我怎么就攤上這事汉操≡倮矗” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵磷瘤,是天一觀的道長芒篷。 經(jīng)常有香客問我,道長采缚,這世上最難降的妖魔是什么针炉? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮扳抽,結(jié)果婚禮上篡帕,老公的妹妹穿的比我還像新娘殖侵。我一直安慰自己,他們只是感情好镰烧,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布拢军。 她就那樣靜靜地躺著,像睡著了一般怔鳖。 火紅的嫁衣襯著肌膚如雪茉唉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天结执,我揣著相機(jī)與錄音度陆,去河邊找鬼。 笑死献幔,一個胖子當(dāng)著我的面吹牛懂傀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斜姥,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸿竖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了铸敏?” 一聲冷哼從身側(cè)響起缚忧,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杈笔,沒想到半個月后闪水,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蒙具,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年球榆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片禁筏。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡持钉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篱昔,到底是詐尸還是另有隱情每强,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布州刽,位于F島的核電站空执,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏穗椅。R本人自食惡果不足惜辨绊,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匹表。 院中可真熱鬧门坷,春花似錦宣鄙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至敏簿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宣虾,已是汗流浹背惯裕。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留绣硝,地道東北人蜻势。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像鹉胖,于是被迫代替她去往敵國和親握玛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,208評論 0 3
  • cheerio是一個node的庫甫菠,可以理解為一個Node.js版本的jquery挠铲,用來從網(wǎng)頁中以 css sele...
    LuciferTM閱讀 4,029評論 0 2
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計者無需花費時間糾纏JS復(fù)雜的高級特性寂诱。 1....
    LaBaby_閱讀 1,336評論 0 2
  • 通過jQuery拂苹,您可以選取(查詢痰洒,query)HTML元素瓢棒,并對它們執(zhí)行“操作”(actions)。 jQuer...
    枇杷樹8824閱讀 657評論 0 3
  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化丘喻,入門級到專家級脯宿,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,586評論 0 7