通读cheerio API-网络爬虫

所谓工欲善其事,必先利其器,所以通读了cheerio的API,顺便翻译了2次,有些地点因为了解的比较少,不知底哪些看头,保留了英文,希望各位不吝告诉自个儿,然后一起把那么些翻译完结。

###cheerio

为服务器特别定制的,飞速、灵活、实施的jQuery主题达成.

###Introduction

将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>

###Installation

npm install cheerio

###Features

**❤ 相似的语法:**Cheerio 包蕴了 jQuery
宗旨的子集。Cheerio  从jQuery库中去除了具备
DOM不相同性和浏览器狼狈的有的,揭破了它真的优雅的API。

**ϟ 打雷般的块:**Cheerio
工作在一个非凡简单,一致的DOM模型之上。解析,操作,呈送都变得难以置信的高效。基础的端到端的基准测试展现Cheerio
大约比JSDOM快八倍(8x)。

❁ 巨灵活: Cheerio 封装了卓越的htmlparser。Cheerio
大致力所能及分析任何的 HTML 和 XML document。

###What about JSDOM

作者写cheerio
是因为本人发现自家要好对JSDOM越来越消极。对于作者的话,总是会贰次又3次的冲击多少个难题。

  • JSDOM内建的分析太过分严格:
    JSDOM附带的HTML解析不可能处理很多及时的公众的网站。
  • JSDOM太慢:用JSDOM解析大型网站存在可见的推移。
  • JSDOM太累赘:JSDOM的对象是提供多少个大家在浏览器里面来看的一律的
    DOM
    环境。笔者从不曾真的须求有所那么些东西,笔者只是想要3个简便的,相似的方法去处理HTML。

###When I would use JSDOM

Cheerio
不会化解你的拥有标题。作者人会利用JSDOM如若自己索要用三个在服务器上的浏览器环境,尤其是只要小编想要自动化一些效应测试。

###API

####小编们将运用的符号示例

<ul id=“fruits”>

<li class=“apple”>Apple</li>

<li class=“orange”>Orange</li>

<li class=“pear”>Pear</li>

</ul>

那是大家将会在享有的API例子中用到的HTML标记

####Loading

首先你须要加载HTML。这一步对jQuery来说是必须的,since
jQuery operates on the one, baked-in DOM。通过Cheerio,大家需求把HTML
document 传进去。

这是首选:

var cheerio = require(‘cheerio’),

    $ = cheerio.load(‘<ul id=”fruits”>…</ul>’);

要么经过传递字符串作为内容来加载HTML:

$ = require(‘cheerio’);

$(‘ul’, ‘<ul
id=”fruits”>…</ul>’);

Or as the root:

$ = require(‘cheerio’);

$(‘li’, ‘ul’, ‘<ul
id=”fruits”>…</ul>’);

你也得以传递3个附加的靶子给.load()倘使您供给改变任何的私下认可解析选项的话:

$ = cheerio.load(‘<ul id=”fruits”>…</ul>’, {

    ignoreWhitespace:
true,

    xmlMode: true

});

那一个分析选项皆以一贯来源于htmlparser
,因而任何在htmlparser里有效的选项在Chreeio里也是行得通的。默许的选项如下:

{

    ignoreWhitespace:
false,

    xmlMode: false,

    lowerCaseTags:
false

}

想看选项清单和它们都意义,看

这个

这个

####Selectors

Cheerio的取舍器用起来大致和jQuery一样,所以API也很相似。

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

选拔器在 Context
范围内搜索,Context又在Root范围内搜寻。selector
和context不过是三个字符串表达式,DOM成分,和DOM成分的数组,大概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)

收获和改动属性。在合营的因素中只好获取第1要素的性质。借使设置叁本性质的值为null,则移除那个天性。你也可以传递一对键值,或然一个函数。

$(‘ul’).attr(‘id’)

//=> fruits

 

$(‘.apple’).attr(‘id’, ‘favorite’).html()

//=> <li class=”apple”
id=”favorite”>Apple</li>

越多消息请看这里

value([value])

赢得和改动input,select,textarea的value.注意:
对于传递键值和函数的支撑还未曾被加进去。

$(‘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.也得以传函数。

$(‘.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将会被剔除,也能够传函数。

$(‘.pear’).removeClass(‘pear’).html()

//=> <li class=””>Pear</li>

 

$(‘.apple’).addClass(‘red’).removeClass().html()

//=> <li class=””>Apple</li>

越来越多音信看这里

.is.(selector)

.is(function(index))

有任何因素匹配selector就回去true。如若运用判定函数,判定函数在当选的要素中执行,所以this指向当前的成分。

####Traversing

.find(selector)

获得1个在同盟的因素中由接纳器滤过的子孙。

$(‘#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])

对于每一种集合内的要素,通过测试这些因素和DOM层级关系上的先人成分,获得第②个门户卓殊的因素

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

赢得选定范围内的因素

$(‘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对象,为每种匹配成分执行1个函数。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.要提前跳出循环,再次来到false.

var fruits = [];

 

$(‘li’).each(function(i, elem)
{

  fruits[i] =
$(this).text();

});

 

fruits.join(‘, ‘);

//=> Apple, Orange, Pear

.map(function(index,element))

迭代一个cheerio对象,为各种匹配成分执行三个函数。Map会重回一个迭代结果的数组。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))

迭代3个cheerio对象,滤出匹配采用器也许是传进去的函数的因素。要是使用函数方法,这些函数在被采纳的要素中施行,所以this指向的手势当前因素。

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对象的第2个成分

$(‘#fruits’).children().first().text()

//=> Apple

.last()

$(‘#fruits’).children().last().text()

//=> Pear

会接纳chreeio对象的结尾2个成分

.eq(i)

通过索引筛选匹配的成分。使用.eq(-i)就从最后二个因素向前数。

$(‘li’).eq(0).text()

//=> Apple

 

$(‘li’).eq(-1).text()

//=> Pear

###Manipulation

变动DOM结构的点子

.append(content,[content…])

在种种元素最终插入3个子成分

$(‘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,…])

在各个成分最前插入2个子成分

$(‘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有内容的话,将会替代原先的HTML

$(‘.orange’).html()

//=> Orange

 

$(‘#fruits’).html(‘<li class=”mango”>Mango</li>’).html()

//=> <li class=”mango”>Mango</li>

.text( [textString] )

获得成分的text内容,包蕴子成分。假设textString被钦赐的话,种种成分的text内容都会被轮换。

$(‘.orange’).text()

//=> Orange

 

$(‘ul’).text()

//=>  Apple

//    Orange

//    Pear

###Rendering

若果你想呈送document,你能利用html多功效函数。

$.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>

暗中同意的,html会让部分标签保持开标签的状态.有时候你想表现3个实用的XML文书档案.例如上边这几个:

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

下一场为了表现那些XML,你供给选择xml那一个函数:

$.xml()

//=>  <media:thumbnail
url=”http://www.foo.com/keyframe.jpg” width=”75″ height=”50″
time=”12:05:01.123″/>

###Miscellaneous

不属于别的地方的DOM 成分方法

.toArray()

获取具有的在DOM元素,转化为数组、

$(‘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节点数组。context参数对chreeio没有意思,不过用来保障APi的包容性。

###Screencasts

http://vimeo.com/31950192

其一录像教程是follow-up Nettut的”How to Scrape Web
Pages with Node.js and jQuery”,用 cheerio而不是JSDOM+JQuery.
那个录像就是显得chreeio多牛B,多快的。