Cheerio模块
2017-05-16 本文已影响429人
Evtion
jquery库是前端操作dom节点的一把利手;在后端模块,cheerio模块是爬虫脚本用得最多的模块,主要用来获取爬取到的节点,cheeio模块的github地址是cheerio模块;下面看一下作者的文档。
1. Cheerio简介:
-
cheerio:专为服务端设计的快速、灵活和精简实现的核心jquery。
- 特点:
- 相似性:Cheerio模块引入了jquery核心的一部分,去除了jquery库中所有在DOM和浏览器的不兼容部分,只保留了它主要核心API。
- 快速性:Cheerio依靠简单、一致的DOM模型运行工作,因此,解析,操作和渲染是非常高效的。初步的端到端的基准测试表明,cheerio大约比 jsdom (相类似模块)快8倍。
- 灵活性:Cheerio遵循@FB55's宽松的htmlparser2语法,Cheerio可以解析几乎所有html或XML文档。
- 安装:命令如下:
npm install cheerio
- 特点:
-
Cheerio不是web浏览器:
- Cheerio 解析语法标签和提供了一套遍历和操作数据的结构的API,它不像web浏览器那样去解释结果。特别地,它不会产生可视化渲染,应用CSS,加载外部资源,或执行JavaScript。如果您使用的情况需要这个功能,你应该考虑这样的项目 jsdom 或 PhantomJS。
2. Cheerio示例代码:
const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')
$('h2.title').text('Hello there!')
$('h2').addClass('welcome')
$.html()
//=> <h2 class="title welcome">Hello there!</h2>
3. API 说明:
- 以下是用来说明API的实例html标签代码:
<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
<li class="pear">Pear</li>
</ul>
-
加载loading:
- 首先,你需要加载html文档;当jquery操作一份DOM文档时,这一步骤在jquery中是必须的。我们需要通过Cheerio加载html文档,下面方法是首先的方法:
const cheerio = require('cheerio');
const $ = cheerio.load('<ul id="fruits">...</ul>');
```
- 或者,也可以通过将字符串作为上下文加载到HTML中:
```
const $ = require('cheerio');
$('ul', '<ul id="fruits">...</ul>');
```
- 又或者作为根元素:
```
const $ = require('cheerio');
$('li', 'ul', '<ul id="fruits">...</ul>');
```
- 如果需要修改任何默认解析选项,你可以通过一个额外的对象给load()方法:
```
const $ = cheerio.load('<ul id="fruits">...</ul>', {
normalizeWhitespace: true,
xmlMode: true
});
```
- 这些options选项直接继承自htmlpaser2语法,因此任何选项来自htmlparser在cheerio中是可以直接使用的。下面是默认的options选项值:
```
{
withDomLvl1: true,
normalizeWhitespace: false,
xmlMode: false,
decodeEntities: true
}
```
- 要详细了解这些默认的options选项可以参考htmlparser2的options。
-
选择器(Selectors):
- cheerio的选择器的实现和jQuery几乎是相同,所以cheerio的API和jQuery也相似。
- $( selector, [context], [root] ):
- 选择器在Context(上下文)范围内搜索;Context又在根元素下搜索。Context和selector可以是字符串表达式,DOM元素,DOM元素数组或cheerio对象。root通常是html文档字符串。
- 这个选择器的起点是遍历和操作文档。与jquery相似的地方,这是在文档选择元素的主要方法;与jQuery不同的地方是,它建立在CSSSelect库之上。它实现了大部分更好的选择器。
$('.apple', '#fruits').text() //=> Apple $('ul .pear').attr('class') //=> pear $('li[class=orange]').html() //=> Orange
-
属性(Attributes):
- 获取和修改属性的方法。
- .attr( name, value ):
- 获取和设置属性的方法,在匹配到的元素当中,这个方法只能获取到第一个匹配元素的属性。如果你设置属性的值为null,就相当于你删除了这个属性;你也可以传递一个键值对或一个函数给attr()方法。
$('ul').attr('id') //=> fruits $('.apple').attr('id', 'favorite').html() //=> <li class="apple" id="favorite">Apple</li>
- 浏览 [http://api.jquery.com/attr/](http://api.jquery.com/attr/) 获取更多信息。
- .prop( name, value ):
- 获取和设置属性值的方法。在匹配到的元素当中,这个方法只能获取到第一个匹配元素的属性。
$('input[type="checkbox"]').prop('checked') //=> false $('input[type="checkbox"]').prop('checked', true).val() //=> ok
- 浏览 [http://api.jquery.com/prop/](http://api.jquery.com/prop/)获取更多信息。
- .data( name, value ):
- 获取和设置属性值的方法。在匹配到的元素当中,这个方法只能获取或设置到第一个匹配元素的属性值。
$('<div data-apple-color="red"></div>').data() //=> { appleColor: 'red' } $('<div data-apple-color="red"></div>').data('apple-color') //=> 'red' const apple = $('.apple').data('kind', 'mac') apple.data('kind') //=> 'mac'
- 浏览 [http://api.jquery.com/data/](http://api.jquery.com/data/) 获取更多信息。
- .val( [value] ):
- 获取或设置nput, select, and textarea的方法,注意:关于键值对和函数的支持至今还没有被加入。
$('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>
- .addClass( className ):
- 为所有匹配到的元素添加类名(class),可以像jQuery一样接收函数作为参数。
$('.pear').addClass('fruit').html() //=> <li class="pear fruit">Pear</li> $('.apple').addClass('fruit red').html() //=> <li class="apple fruit red">Apple</li>
- .hasClass( className ):
- 判断匹配到的元素是否具有这个className值。
$('.pear').hasClass('pear') //=> true $('apple').hasClass('fruit') //=> false $('li').hasClass('pear') //=> true
- .removeClass( [className] ):
- 移除选择匹配到的元素一个或多个用空格进行分隔的类。如果没有传入类名,则所有的类将会被移除,它可以像jQuery一样接受函数作为参数。
$('.pear').removeClass('pear').html() //=> <li class="">Pear</li> $('.apple').addClass('red').removeClass().html() //=> <li class="">Apple</li>
- .toggleClass( className, [switch] ):
- 为匹配到的元素添加或移除类,添加或移除取决于类的存在与否或开关参数的值。它可以像jQuery一样接受function作为参数值。
$('.apple.green').toggleClass('fruit green red').html() //=> <li class="apple fruit red">Apple</li> $('.apple.green').toggleClass('fruit green red', true).html() //=> <li class="apple green fruit red">Apple</li>
- .is( selector /element /selection/function(index)):
- 检查当前元素列表,如果元素中的任何元素与选择器匹配,则返回true。
- 如果使用一个元素或cheerio selection,如果有任何的元素匹配,返回true。
- 如果使用判断函数,函数将在所选元素的上下文中执行,所以判断这是当前元素。
-
表单(Forms):
- .serializeArray():
- 将一个表单元素序列化成一个键值对的对象数组。
$('<form><input name="foo" value="bar" /></form>').serializeArray() //=> [ { name: 'foo', value: 'bar' } ]
- .serializeArray():
-
遍历(Traversing)
- .find([selector|selection|node]):
- 获取当前匹配元素的每个元素的后代,由选择器、jQuery对象或元素进行过滤。
$('#fruits').find('li').length //=> 3 $('#fruits').find($('.apple')).length //=> 1
- .parent([selector]):
- 获取当前匹配元素集中的每个元素的父元素。特别地,可以通过选择器筛选。
$('.pear').parent().attr('id') //=> fruits
- .parents([selector]):
- 获取一组匹配元素中的父集,通过每个元素的选择器进行过滤。
$('.orange').parents().length // => 2 $('.orange').parents('#fruits').length // => 1
- parentsUntil([selector][,filter])
- 获取当前匹配的元素集的每一个元素的父集,直到根元素但不包含DOM节点,cheerio对象,选择器匹配到元素。
$('.orange').parentsUntil('#food').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([selector])
- 获取第一个匹配元素的下一个同级元素,可选地,可以由选择器进行筛选。
$('.apple').next().hasClass('orange') //=> true
- .nextAll([selector]):
- 获取第一个匹配元素的所有后面兄弟姐妹节点,可选地,可以由选择器进行过滤。
$('.apple').nextAll() //=> [<li class="orange">Orange</li>, <li class="pear">Pear</li>] $('.apple').nextAll('.orange') //=> [<li class="orange">Orange</li>]
- .nextUntil([selector], [filter])
- 获取所有以下的兄弟姐妹,但不包括选择器匹配的元素,可选地,可以由另一选择器进行过滤。
$('.apple').nextUntil('.pear') //=> [<li class="orange">Orange</li>]
- .prev([selector])
- 获取由选择器筛选的第一个选择元素的前一个同级元素。
$('.orange').prev().hasClass('apple') //=> true
- .prevAll([selector])
- 获取第一个选择元素的所有前兄弟姐妹元素,可选地,可以由选择器过滤。
$('.pear').prevAll() //=> [<li class="orange">Orange</li>, <li class="apple">Apple</li>] $('.pear').prevAll('.orange') //=> [<li class="orange">Orange</li>]
- .prevUntil([selector], [filter])
- 获取所有前面兄弟姐妹元素,但不包括选择器匹配的元素,可选地,可以由另外一个选择器来筛选。
$('.pear').prevUntil('.apple') //=> [<li class="orange">Orange</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
- .contents()
- 获取匹配元素集中每个元素的子元素,包括文本和注释节点。
$('#fruits').contents().length//=> 3
- .each( function(index, element) )
- 遍历一个Cheerio对象,为每一个匹配到的元素执行一个function函数,当回调被触发时,函数将在DOM元素的上下文中被触发。这是指当前元素,它相当于函数参数元素。要提早退出每个循环,返回假(布尔值)。
const fruits = []; $('li').each(function(i, elem) { fruits[i] = $(this).text(); }); fruits.join(', '); //=> Apple, Orange, Pear
- .map( function(index, element) )
- 传递每一个在当前匹配到集合中的元素给function函数,函数返回一个新的包含返回值的Cheerio对象。函数可以返回要插入结果集的单个数据项或数据项数组。如果返回了一个数组,在数组里面的元素将会插入到返回集中。如果function返回null或undefined,那么没有元素会被插入。
$('li').map(function(i, el) { // this === el return $(this).text(); }).get().join(' '); //=> "apple orange pear"
- .filter( selector | selection | element | function ( index , element) )
- 遍历一个cheerio对象,减少组选择器匹配的元素的选择器或传递函数的测试。当cheerio的seletion被指定时,只返回selection选择包含的选择元素。当一个element(元素)被指定时,只返回该元素(如果它是包含在原始的选择)。如果使用function函数的方法,函数的上下文中执行选定的元素,这是指当前元素。
- Selector:
$('li').filter('.orange').attr('class'); //=> orange
- function:
$('li').filter(function(i, el) { // this === el return $(this).attr('class') === 'orange'; }).attr('class') //=> orange
- .not( selector | selection | element | function(index, elem) ):
- 删除匹配的元素集合中的元素。
- .find([selector|selection|node]):