├── .gitignore ├── .mds-list ├── sync-en.sh ├── readme.md └── en.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | fork 4 | source 5 | hub-create.sh -------------------------------------------------------------------------------- /.mds-list: -------------------------------------------------------------------------------- 1 | ./source/History.md 2 | ./source/Readme.md 3 | ./source/CONTRIBUTING.md 4 | ./source/.github/issue_template.md 5 | 6 | -------------------------------------------------------------------------------- /sync-en.sh: -------------------------------------------------------------------------------- 1 | cat './.mds-list' | while read line || [[ -n ${line} ]] 2 | do 3 | testseq="zh.md" 4 | if [[ $line =~ $testseq || "$line" == "" ]]; then 5 | echo "skip $line" 6 | else 7 | lowline=`echo "$line" | awk '{print tolower($0)}'` 8 | # lowwer string 9 | zh=${line//source\//} 10 | dir=$(dirname $zh) 11 | 12 | source_readme="./source/readme.md" 13 | if [[ $lowline == $source_readme ]];then 14 | # source/[readme|REAMDE].md => en.md 15 | filename="en.md" 16 | else 17 | # source/other.md => ./other.md 18 | filename=$(basename $zh) 19 | fi 20 | echo "$line >> $dir/$filename" 21 | mkdir -p $dir && cp $line "$_/$filename" 22 | fi 23 | done -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # cheeriojs/cheerio [![explain]][source] [![translate-svg]][translate-list] 2 | 3 | 4 | 5 | [explain]: http://llever.com/explain.svg 6 | [source]: https://github.com/chinanf-boy/Source-Explain 7 | [translate-svg]: http://llever.com/translate.svg 8 | [translate-list]: https://github.com/chinanf-boy/chinese-translate-list 9 | [size-img]: https://packagephobia.now.sh/badge?p=Name 10 | [size]: https://packagephobia.now.sh/result?p=Name 11 | 12 | 「 快, 灵活 & 轻 的 jQuery 核心实现,特别为服务器端(Node)设计。 」 13 | 14 | [中文](./readme.md) | [english](https://github.com/cheeriojs/cheerio) 15 | 16 | --- 17 | 18 | ## 校对 ✅ 19 | 20 | 21 | 22 | 23 | 24 | 25 | | 翻译的原文 | 与日期 | 最新更新 | 更多 | 26 | | ---------- | ------------- | -------- | -------------------------- | 27 | | [commit] | ⏰ 2019-04-22 | ![last] | [中文翻译][translate-list] | 28 | 29 | [last]: https://img.shields.io/github/last-commit/cheeriojs/cheerio.svg 30 | [commit]: https://github.com/cheeriojs/cheerio/tree/7a9ff22f68bd6dbdf04f8e3a52e28a6b369b5fa7 31 | 32 | 33 | 34 | ### 贡献 35 | 36 | 欢迎 👏 勘误/校对/更新贡献 😊 [具体贡献请看](https://github.com/chinanf-boy/chinese-translate-list#贡献) 37 | 38 | ## 生活 39 | 40 | [help me live , live need money 💰](https://github.com/chinanf-boy/live-need-money) 41 | 42 | --- 43 | 44 |

cheerio

45 | 46 |
快, 灵活 & 轻 的jQuery 核心实现,特别为服务器端设计。
47 | 48 |
49 | 50 | Travis CI 51 | 52 | 53 | Coverage 54 | 55 | 56 | Join the chat at https://gitter.im/cheeriojs/cheerio 57 | 58 | 59 | OpenCollective backers 60 | 61 | 62 | OpenCollective sponsors 63 | 64 |
65 | 66 |
67 | 68 | ```js 69 | const cheerio = require('cheerio'); 70 | const $ = cheerio.load('

Hello world

'); 71 | 72 | $('h2.title').text('Hello there!'); 73 | $('h2').addClass('welcome'); 74 | 75 | $.html(); 76 | //=>

Hello there!

77 | ``` 78 | 79 | ## 注意 80 | 81 | 我们目前正在 `master`分支,致力 cheerio 1.0.0 版本的发布。上次源代码发布的版本是,`0.22.0`, 可以在[这里](https://github.com/cheeriojs/cheerio/tree/aa90399c9c02f12432bfff97b8f1c7d8ece7c307)找到。 82 | 83 | ## 安装 84 | 85 | `npm install cheerio` 86 | 87 | ## 特征 88 | 89 | **❤ 熟悉的语法:** Cheerio 实现了 jQuery 核心 的一个子集。Cheerio 从 jQuery 库中,删除了所有 DOM 和浏览器不一致的残骸,揭示了它真正华丽的 API。 90 | 91 | **ϟ 非常快:**Cheerio 使用非常简单,一致的 DOM 模型。因此,解析,操纵和渲染非常有效。初步的端到端基准测试表明,cheerio 是**8x**快于 JSDOM 。 92 | 93 | **❁ 非常灵活:**Cheerio 围绕 @FB55 宽松的[htmlparser2](https://github.com/fb55/htmlparser2/)解析器展开。Cheerio 几乎可以解析,任何 HTML 或 XML 文档。 94 | 95 | ## Cheerio 不是网络浏览器 96 | 97 | Cheerio 解析(html)标记,并提供用于遍历/操纵,结果数据结构的 API。它不会像 Web 浏览器那样解释结果。具体来说,并*不会*生成可视化渲染,应用 CSS,加载外部资源或执行 JavaScript。如果您的用例,需要任何此功能,您应该考虑像其他项目:[PhantomJS](http://phantomjs.org/)要么[JSDom](https://github.com/tmpvar/jsdom)。 98 | 99 | ## API 100 | 101 | ### 目录 102 | 103 |
104 | Selectors (选择器) 105 | 106 | - [\$( selector, \[context\], \[root\] )](#-selector-context-root-) 107 | 108 |
109 |
110 | 属性 111 | 112 | - [.attr( name, value )](#attr-name-value-) 113 | - [.prop( name, value )](#prop-name-value-) 114 | - [.data( name, value )](#data-name-value-) 115 | - [.val( \[value\] )](#val-value-) 116 | - [.removeAttr( name )](#removeattr-name-) 117 | - [.hasClass( className )](#hasclass-classname-) 118 | - [.addClass( className )](#addclass-classname-) 119 | - [.removeClass( \[className\] )](#removeclass-classname-) 120 | - [.toggleClass( className, \[switch\] )](#toggleclass-classname-switch-) 121 | - [.is( selector )](#is-selector-) 122 | - [.is( element )](#is-element-) 123 | - [.is( selection )](#is-selection-) 124 | - [.is( function(index) )](#is-functionindex-) 125 | 126 |
127 |
128 | 表单 129 | 130 | - [.serialize()](#serialize) 131 | - [.serializeArray()](#serializearray) 132 | 133 |
134 |
135 | 遍历 136 | 137 | - [.find(selector)](#findselector) 138 | - [.find(selection)](#findselection) 139 | - [.find(node)](#findnode) 140 | - [.parent(\[selector\])](#parentselector) 141 | - [.parents(\[selector\])](#parentsselector) 142 | - [.parentsUntil(\[selector\]\[,filter\])](#parentsuntilselectorfilter) 143 | - [.closest(selector)](#closestselector) 144 | - [.next(\[selector\])](#nextselector) 145 | - [.nextAll(\[selector\])](#nextallselector) 146 | - [.nextUntil(\[selector\], \[filter\])](#nextuntilselector-filter) 147 | - [.prev(\[selector\])](#prevselector) 148 | - [.prevAll(\[selector\])](#prevallselector) 149 | - [.prevUntil(\[selector\], \[filter\])](#prevuntilselector-filter) 150 | - [.slice( start, \[end\] )](#slice-start-end-) 151 | - [.siblings(\[selector\])](#siblingsselector) 152 | - [.children(\[selector\])](#childrenselector) 153 | - [.contents()](#contents) 154 | - [.each( function(index, element) )](#each-functionindex-element-) 155 | - [.map( function(index, element) )](#map-functionindex-element-) 156 | - [.filter( selector )
157 | .filter( selection )
158 | .filter( element )
159 | .filter( function(index, element) )](#filter-selector---filter-selection---filter-element---filter-functionindex-element-) 160 | - [.not( selector )
161 | .not( selection )
162 | .not( element )
163 | .not( function(index, elem) )](#not-selector---not-selection---not-element---not-functionindex-elem-) 164 | - [.has( selector )
165 | .has( element )](#has-selector---has-element-) 166 | - [.first()](#first) 167 | - [.last()](#last) 168 | - [.eq( i )](#eq-i-) 169 | - [.get( \[i\] )](#get-i-) 170 | - [.index()](#index) 171 | - [.index( selector )](#index-selector-) 172 | - [.index( nodeOrSelection )](#index-nodeorselection-) 173 | - [.end()](#end) 174 | - [.add( selector \[, context\] )](#add-selector--context-) 175 | - [.add( element )](#add-element-) 176 | - [.add( elements )](#add-elements-) 177 | - [.add( html )](#add-html-) 178 | - [.add( selection )](#add-selection-) 179 | - [.addBack( \[filter\] )](#addback-filter-) 180 | 181 |
182 |
183 | 操纵 184 | 185 | - [.append( content, \[content, ...\] )](#append-content-content--) 186 | - [.appendTo( target )](#appendto-target-) 187 | - [.prepend( content, \[content, ...\] )](#prepend-content-content--) 188 | - [.prependTo( target )](#prependto-target-) 189 | - [.after( content, \[content, ...\] )](#after-content-content--) 190 | - [.insertAfter( target )](#insertafter-target-) 191 | - [.before( content, \[content, ...\] )](#before-content-content--) 192 | - [.insertBefore( target )](#insertbefore-target-) 193 | - [.remove( \[selector\] )](#remove-selector-) 194 | - [.replaceWith( content )](#replacewith-content-) 195 | - [.empty()](#empty) 196 | - [.html( \[htmlString\] )](#html-htmlstring-) 197 | - [.text( \[textString\] )](#text-textstring-) 198 | - [.wrap( content )](#wrap-content-) 199 | - [.css( \[propertName\] )
200 | .css( \[ propertyNames\] )
201 | .css( \[propertyName\], \[value\] )
202 | .css( \[propertName\], \[function\] )
203 | .css( \[properties\] )](#css-propertname---css--propertynames---css-propertyname-value---css-propertname-function---css-properties-) 204 | 205 |
206 | 207 | ### 我们将使用的标记示例: 208 | 209 | ```html 210 | 215 | ``` 216 | 217 | 这里的 HTML 标记,是我们所有 API 示例的。 218 | 219 | ### 载入中 220 | 221 | 首先,您需要加载 HTML。jQuery 中的这一步是隐含的,因为 jQuery 在一个烤着的 DOM 上运行的。而 Cheerio,我们是需要传递 HTML 文档给它。 222 | 223 | 这是*首选*方法: 224 | 225 | ```js 226 | const cheerio = require('cheerio'); 227 | const $ = cheerio.load(''); 228 | ``` 229 | 230 | 或者,您也可以通过,将字符串作为上下文传递,来加载 HTML: 231 | 232 | ```js 233 | const $ = require('cheerio'); 234 | $('ul', ''); 235 | ``` 236 | 237 | 或者直接选择`li`元素: 238 | 239 | ```js 240 | const $ = require('cheerio'); 241 | $('li', 'ul', ''); 242 | ``` 243 | 244 | `.load()`还可以传递一个额外的对象,如果您需要修改任何默认解析选项的话: 245 | 246 | ```js 247 | const $ = cheerio.load('', { 248 | normalizeWhitespace: true, 249 | xmlMode: true 250 | }); 251 | ``` 252 | 253 | 这些解析选项,直接来自[htmlparser2](https://github.com/fb55/htmlparser2/wiki/Parser-options),因此,任何`htmlparser2`可用的选项,在 cheerio 中也有效。默认选项是: 254 | 255 | ```js 256 | { 257 | withDomLvl1: true, 258 | normalizeWhitespace: false, 259 | xmlMode: false, 260 | decodeEntities: true 261 | } 262 | ``` 263 | 264 | 有关选项及其效果的完整列表,请参阅[这里](https://github.com/fb55/DomHandler)和[htmlparser2 的选项](https://github.com/fb55/htmlparser2/wiki/Parser-options)。 265 | 266 | ### 选择器 267 | 268 | Cheerio 的选择器实现,几乎与 jQuery 相同,因此 API 非常相似。 269 | 270 | #### \$( selector, [context], [root] ) 271 | 272 | `selector`,会搜索`context`范围,而该范围又是从`root`范围搜索而来。`selector`和`context`可以是字符串表达式,DOM 元素,DOM 元素数组或 cheerio 对象。`root`通常是 HTML 文档字符串。 273 | 274 | 此选择器方法是遍历和操纵文档的起点。像 jQuery 一样,它是在文档中,选择元素的主要方法,但与 jQuery 不同,我们是构建在 CSSSelect 库之上的,实现了大多数的 Sizzle 选择器。 275 | 276 | ```js 277 | $('.apple', '#fruits').text(); 278 | //=> Apple 279 | 280 | $('ul .pear').attr('class'); 281 | //=> pear 282 | 283 | $('li[class=orange]').html(); 284 | //=> Orange 285 | ``` 286 | 287 | ##### XML Namespaces 288 | 289 | 您可以选择 XML 命名空间,但是[其实遵循 CSS 规范](https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#attribute-selectors),冒号(`:`)需要进行转义,才能使选择器有效。 290 | 291 | ```js 292 | $('[xml\\:id="main"'); 293 | ``` 294 | 295 | ### 属性 296 | 297 | 获取和修改属性的方法。 298 | 299 | #### .attr( name, value ) 300 | 301 | 获取和设置属性的方法。仅获取匹配集里面,第一个元素的属性值。如果将属性的值设置为`null`,就删除该属性。你也可以传递一个`map`和`function`,就像 jQuery。 302 | 303 | ```js 304 | $('ul').attr('id'); 305 | //=> fruits 306 | 307 | $('.apple') 308 | .attr('id', 'favorite') 309 | .html(); 310 | //=>
  • Apple
  • 311 | ``` 312 | 313 | > 看到,获得更多信息 314 | 315 | #### .prop( name, value ) 316 | 317 | 获取和设置属性的方法。仅获取匹配集里面,第一个元素的属性值。 318 | 319 | ```js 320 | $('input[type="checkbox"]').prop('checked'); 321 | //=> false 322 | 323 | $('input[type="checkbox"]') 324 | .prop('checked', true) 325 | .val(); 326 | //=> ok 327 | ``` 328 | 329 | > 看到,获得更多信息 330 | 331 | #### .data( name, value ) 332 | 333 | 获取和设置数据属性的方法。仅获取或设置匹配集里面,第一个元素的数据属性值。 334 | 335 | ```js 336 | $('
    ').data(); 337 | //=> { appleColor: 'red' } 338 | 339 | $('
    ').data('apple-color'); 340 | //=> 'red' 341 | 342 | const apple = $('.apple').data('kind', 'mac'); 343 | apple.data('kind'); 344 | //=> 'mac' 345 | ``` 346 | 347 | > 看到,获得更多信息 348 | 349 | #### .val( [value] ) 350 | 351 | 获取和设置 input,select 和 textarea 的值的方法。注意:`map`,和`function`支持尚未添加。 352 | 353 | ```js 354 | $('input[type="text"]').val(); 355 | //=> input_text 356 | 357 | $('input[type="text"]') 358 | .val('test') 359 | .html(); 360 | //=> 361 | ``` 362 | 363 | #### .removeAttr( name ) 364 | 365 | 删除`name`属性的方法。 366 | 367 | ```js 368 | $('.pear') 369 | .removeAttr('class') 370 | .html(); 371 | //=>
  • Pear
  • 372 | ``` 373 | 374 | #### .hasClass( className ) 375 | 376 | 检查是否,匹配的 _任何_ 元素,具有给定的`className`。 377 | 378 | ```js 379 | $('.pear').hasClass('pear'); 380 | //=> true 381 | 382 | $('apple').hasClass('fruit'); 383 | //=> false 384 | 385 | $('li').hasClass('pear'); 386 | //=> true 387 | ``` 388 | 389 | #### .addClass( className ) 390 | 391 | 将类添加到所有匹配的元素。也接受一个`function`,就像 jQuery。 392 | 393 | ```js 394 | $('.pear') 395 | .addClass('fruit') 396 | .html(); 397 | //=>
  • Pear
  • 398 | 399 | $('.apple') 400 | .addClass('fruit red') 401 | .html(); 402 | //=>
  • Apple
  • 403 | ``` 404 | 405 | > 看到,获得更多信息。 406 | 407 | #### .removeClass( [className] ) 408 | 409 | 从所选元素中,删除一个或多个以空格分隔的类。如果没有指定的`className`,则删除所有类。也接受一个`function`,就像 jQuery。 410 | 411 | ```js 412 | $('.pear') 413 | .removeClass('pear') 414 | .html(); 415 | //=>
  • Pear
  • 416 | 417 | $('.apple') 418 | .addClass('red') 419 | .removeClass() 420 | .html(); 421 | //=>
  • Apple
  • 422 | ``` 423 | 424 | > 看到,获得更多信息。 425 | 426 | #### .toggleClass( className, [switch] ) 427 | 428 | 根据类的存在与否,或 switch 参数的值,从匹配的元素中,添加或删除类。也接受一个`function`,就像 jQuery。 429 | 430 | ```js 431 | $('.apple.green') 432 | .toggleClass('fruit green red') 433 | .html(); 434 | //=>
  • Apple
  • 435 | 436 | $('.apple.green') 437 | .toggleClass('fruit green red', true) 438 | .html(); 439 | //=>
  • Apple
  • 440 | ``` 441 | 442 | > 看到,获得更多信息。 443 | 444 | #### .is( selector ) 445 | 446 | #### .is( element ) 447 | 448 | #### .is( selection ) 449 | 450 | #### .is( function(index) ) 451 | 452 | 检查当前的元素列表,如果*任何*元素与 selector 匹配,则返回`true`,。若是 element 或 Cheerio selection,那么*任何*元素匹配则返回`true`。如果使用的是一个 function,则在所选元素的上下文中,执行该函数,而`this`指当前元素。 453 | 454 | ### 表单 455 | 456 | #### .serialize() 457 | 458 | 将一组表单元素,编码为 URL 查询字符串。 459 | 460 | ```js 461 | $( 462 | '
    ' 463 | ).serialize(); 464 | //=> foo=bar&foo=qux 465 | ``` 466 | 467 | #### .serializeArray() 468 | 469 | 将一组表单元素,编码为名称和值的数组。 470 | 471 | ```js 472 | $('
    ').serializeArray(); 473 | //=> [ { name: 'foo', value: 'bar' } ] 474 | ``` 475 | 476 | ### 遍历 477 | 478 | #### .find(selector) 479 | 480 | #### .find(selection) 481 | 482 | #### .find(node) 483 | 484 | 获取当前匹配元素集里面,每个元素的后代。由 selector,jQuery 对象或 element 过滤。 485 | 486 | ```js 487 | $('#fruits').find('li').length; 488 | //=> 3 489 | $('#fruits').find($('.apple')).length; 490 | //=> 1 491 | ``` 492 | 493 | #### .parent([selector]) 494 | 495 | 获取当前匹配元素集里面,每个元素的父元素,可选项为,通过选择器进行过滤。 496 | 497 | ```js 498 | $('.pear') 499 | .parent() 500 | .attr('id'); 501 | //=> fruits 502 | ``` 503 | 504 | #### .parents([selector]) 505 | 506 | 获取当前匹配元素集里面,由`selector`过滤而来的父辈集合 507 | 508 | ```js 509 | $('.orange').parents().length; 510 | // => 2 511 | $('.orange').parents('#fruits').length; 512 | // => 1 513 | ``` 514 | 515 | #### .parentsUntil([selector][,filter]) 516 | 517 | 获取当前匹配元素集里面,每个元素的祖先,但不包括由选择器,DOM 节点或 cheerio 对象匹配的元素。 518 | 519 | ```js 520 | $('.orange').parentsUntil('#food').length; 521 | // => 1 522 | ``` 523 | 524 | #### .closest(selector) 525 | 526 | 对于集合中的每个元素,通过测试元素本身,和遍历 DOM 树中的祖先,来获取与选择器匹配的第一个元素。 527 | 528 | ```js 529 | $('.orange').closest(); 530 | // => [] 531 | $('.orange').closest('.apple'); 532 | // => [] 533 | $('.orange').closest('li'); 534 | // => [
  • Orange
  • ] 535 | $('.orange').closest('#fruits'); 536 | // => [
      ...
    ] 537 | ``` 538 | 539 | #### .next([selector]) 540 | 541 | 获取第一个选定元素的下一个兄弟,可选择让选择器过滤。 542 | 543 | ```js 544 | $('.apple') 545 | .next() 546 | .hasClass('orange'); 547 | //=> true 548 | ``` 549 | 550 | #### .nextAll([selector]) 551 | 552 | 获取第一个选定元素的,所有兄弟节点,可选择让选择器过滤。 553 | 554 | ```js 555 | $('.apple').nextAll(); 556 | //=> [
  • Orange
  • ,
  • Pear
  • ] 557 | $('.apple').nextAll('.orange'); 558 | //=> [
  • Orange
  • ] 559 | ``` 560 | 561 | #### .nextUntil([selector], [filter]) 562 | 563 | 获取以下所有兄弟节点,但不包括选择器匹配的元素,可选择让另一个选择器过滤。 564 | 565 | ```js 566 | $('.apple').nextUntil('.pear'); 567 | //=> [
  • Orange
  • ] 568 | ``` 569 | 570 | #### .prev([selector]) 571 | 572 | 获取第一个选定元素的前一个兄弟,可选择让选择器过滤。 573 | 574 | ```js 575 | $('.orange') 576 | .prev() 577 | .hasClass('apple'); 578 | //=> true 579 | ``` 580 | 581 | #### .prevAll([selector]) 582 | 583 | 获取第一个选定元素的,所有前面兄弟节点,可选择让选择器过滤。 584 | 585 | ```js 586 | $('.pear').prevAll(); 587 | //=> [
  • Orange
  • ,
  • Apple
  • ] 588 | $('.pear').prevAll('.orange'); 589 | //=> [
  • Orange
  • ] 590 | ``` 591 | 592 | #### .prevUntil([selector], [filter]) 593 | 594 | 获取所有前面的兄弟,但不包括选择器匹配的元素,可选择让另一个选择器过滤。 595 | 596 | ```js 597 | $('.pear').prevUntil('.apple'); 598 | //=> [
  • Orange
  • ] 599 | ``` 600 | 601 | #### .slice( start, [end] ) 602 | 603 | 获取,指定范围匹配的元素 604 | 605 | ```js 606 | $('li') 607 | .slice(1) 608 | .eq(0) 609 | .text(); 610 | //=> 'Orange' 611 | 612 | $('li').slice(1, 2).length; 613 | //=> 1 614 | ``` 615 | 616 | #### .siblings([selector]) 617 | 618 | 获取第一个选定元素的兄弟,不包括它自己。 619 | 620 | ```js 621 | $('.pear').siblings().length; 622 | //=> 2 623 | 624 | $('.pear').siblings('.orange').length; 625 | //=> 1 626 | ``` 627 | 628 | #### .children([selector]) 629 | 630 | 获取第一个选定元素的子元素。 631 | 632 | ```js 633 | $('#fruits').children().length; 634 | //=> 3 635 | 636 | $('#fruits') 637 | .children('.pear') 638 | .text(); 639 | //=> Pear 640 | ``` 641 | 642 | #### .contents() 643 | 644 | 获取匹配元素集里面,每个元素的子元素,包括文本和注释节点。 645 | 646 | ```js 647 | $('#fruits').contents().length; 648 | //=> 3 649 | ``` 650 | 651 | #### .each( function(index, element) ) 652 | 653 | 迭代一个 cheerio 对象,为每个匹配的元素执行一个函数。当触发回调时,该函数会在 DOM 元素的上下文中触发,因此`this`指当前元素,它等效于函数参数`element`。要早点打破了`each`循环,返回`false`就行。 654 | 655 | ```js 656 | const fruits = []; 657 | 658 | $('li').each(function(i, elem) { 659 | fruits[i] = $(this).text(); 660 | }); 661 | 662 | fruits.join(', '); 663 | //=> Apple, Orange, Pear 664 | ``` 665 | 666 | #### .map( function(index, element) ) 667 | 668 | 通过函数传递当前匹配集里面的,每个元素,生成包含返回值的新 Cheerio 对象。该函数可以返回单个数据项或数据项数组,插回结果集里面。如果返回数组,则将数组内的元素,插入到集合中。如果函数返回 null 或 undefined,则不会插入任何元素。 669 | 670 | ```js 671 | $('li') 672 | .map(function(i, el) { 673 | // this === el 674 | return $(this).text(); 675 | }) 676 | .get() 677 | .join(' '); 678 | //=> "apple orange pear" 679 | ``` 680 | 681 | #### .filter( selector )
    .filter( selection )
    .filter( element )
    .filter( function(index, element) ) 682 | 683 | 迭代一个 cheerio 对象,将选择器元素集,筛选与选择器匹配的元素或传递函数的测试。指定 Cheerio selection 时,仅返回该选择中,包含的元素。指定 element 时,仅返回该元素(如果它包含在原始选择中)。如果使用函数方法,则在所选元素的上下文中,执行该函数,因此`this`指当前元素。 684 | 685 | 选择器: 686 | 687 | ```js 688 | $('li') 689 | .filter('.orange') 690 | .attr('class'); 691 | //=> orange 692 | ``` 693 | 694 | 函数: 695 | 696 | ```js 697 | $('li') 698 | .filter(function(i, el) { 699 | // this === el 700 | return $(this).attr('class') === 'orange'; 701 | }) 702 | .attr('class'); 703 | //=> orange 704 | ``` 705 | 706 | #### .not( selector )
    .not( selection )
    />.not(function(index,elem)) 707 | 708 | 从匹配元素集里面,删除元素。给出一个,表示一组 DOM 元素的 jQuery 对象的话,`.not()`方法会从匹配元素的子集中,构造新的 jQuery 对象。提供的选择器针对每个元素进行测试; 与选择器不匹配的元素,将包含在结果中。该`.not()`方法与`.filter()`一样,可以用个函数作为它的参数。函数返回 true 的元素,将从过滤集里面排除; 所有其他元素就会包括。 709 | 710 | 选择器: 711 | 712 | ```js 713 | $('li').not('.apple').length; 714 | //=> 2 715 | ``` 716 | 717 | 函数: 718 | 719 | ```js 720 | $('li').not(function(i, el) { 721 | // this === el 722 | return $(this).attr('class') === 'orange'; 723 | }).length; 724 | //=> 2 725 | ``` 726 | 727 | #### .has( selector )
    .has( element ) 728 | 729 | 过滤匹配元素集合,仅留下,有 DOM 匹配元素后代,或与给定选择器匹配的后代元素。相当于`.filter(':has(selector)')`。 730 | 731 | 选择器: 732 | 733 | ```js 734 | $('ul') 735 | .has('.pear') 736 | .attr('id'); 737 | //=> fruits 738 | ``` 739 | 740 | 元素: 741 | 742 | ```js 743 | $('ul') 744 | .has($('.pear')[0]) 745 | .attr('id'); 746 | //=> fruits 747 | ``` 748 | 749 | #### .first() 750 | 751 | 将选择 cheerio 对象的第一个元素 752 | 753 | ```js 754 | $('#fruits') 755 | .children() 756 | .first() 757 | .text(); 758 | //=> Apple 759 | ``` 760 | 761 | #### .last() 762 | 763 | 将选择 cheerio 对象的最后一个元素 764 | 765 | ```js 766 | $('#fruits') 767 | .children() 768 | .last() 769 | .text(); 770 | //=> Pear 771 | ``` 772 | 773 | #### .eq( i ) 774 | 775 | 将匹配元素集,指定为索引处的元素集。使用`.eq(-i)`,会最后的元素,向前计数。 776 | 777 | ```js 778 | $('li') 779 | .eq(0) 780 | .text(); 781 | //=> Apple 782 | 783 | $('li') 784 | .eq(-1) 785 | .text(); 786 | //=> Pear 787 | ``` 788 | 789 | #### .get( [i] ) 790 | 791 | 检索由 Cheerio 对象匹配的 DOM 元素。如果指定了索引,则检索 Cheerio 对象匹配的其中一个元素: 792 | 793 | ```js 794 | $('li').get(0).tagName; 795 | //=> li 796 | ``` 797 | 798 | 如果未指定索引,则检索 Cheerio 对象匹配的所有元素: 799 | 800 | ```js 801 | $('li').get().length; 802 | //=> 3 803 | ``` 804 | 805 | #### .index() 806 | 807 | #### .index( selector ) 808 | 809 | #### .index( nodeOrSelection ) 810 | 811 | 从匹配的元素中,搜索给定元素。 812 | 813 | ```js 814 | $('.pear').index(); 815 | //=> 2 816 | $('.orange').index('li'); 817 | //=> 1 818 | $('.apple').index($('#fruit, li')); 819 | //=> 1 820 | ``` 821 | 822 | #### .end() 823 | 824 | 当前(工作)链中,结束最近的过滤操作,并将匹配元素集返回到先前的状态。 825 | 826 | ```js 827 | $('li') 828 | .eq(0) 829 | .end().length; 830 | //=> 3 831 | ``` 832 | 833 | #### .add( selector [, context] ) 834 | 835 | #### .add( element ) 836 | 837 | #### .add( elements ) 838 | 839 | #### .add( html ) 840 | 841 | #### .add( selection ) 842 | 843 | 将元素添加到匹配元素集。 844 | 845 | ```js 846 | $('.apple').add('.orange').length; 847 | //=> 2 848 | ``` 849 | 850 | #### .addBack( [filter] ) 851 | 852 | 将栈上的前一组元素,添加到当前集合,可选择让选择器过滤。 853 | 854 | ```js 855 | $('li') 856 | .eq(0) 857 | .addBack('.orange').length; 858 | //=> 2 859 | ``` 860 | 861 | ### 操纵 862 | 863 | 修改 DOM 结构的方法。 864 | 865 | #### .append( content, [content, ...] ) 866 | 867 | 插入内容作为,每个选定元素的*最后*子元素。 868 | 869 | ```js 870 | $('ul').append('
  • Plum
  • '); 871 | $.html(); 872 | //=>
      873 | //
    • Apple
    • 874 | //
    • Orange
    • 875 | //
    • Pear
    • 876 | //
    • Plum
    • 877 | //
    878 | ``` 879 | 880 | #### .appendTo( target ) 881 | 882 | 将匹配元素集里面的,每个元素插入到 target 的末尾。 883 | 884 | ```js 885 | $('
  • Plum
  • ').appendTo('#fruits'); 886 | $.html(); 887 | //=>
      888 | //
    • Apple
    • 889 | //
    • Orange
    • 890 | //
    • Pear
    • 891 | //
    • Plum
    • 892 | //
    893 | ``` 894 | 895 | #### .prepend( content, [content, ...] ) 896 | 897 | 插入内容作为,每个选定元素的 _第一个_ 子元素。 898 | 899 | ```js 900 | $('ul').prepend('
  • Plum
  • '); 901 | $.html(); 902 | //=>
      903 | //
    • Plum
    • 904 | //
    • Apple
    • 905 | //
    • Orange
    • 906 | //
    • Pear
    • 907 | //
    908 | ``` 909 | 910 | #### .prependTo( target ) 911 | 912 | 将匹配元素集里面的,每个元素插入到 target 的开头。 913 | 914 | ```js 915 | $('
  • Plum
  • ').prependTo('#fruits'); 916 | $.html(); 917 | //=>
      918 | //
    • Plum
    • 919 | //
    • Apple
    • 920 | //
    • Orange
    • 921 | //
    • Pear
    • 922 | //
    923 | ``` 924 | 925 | #### .after( content, [content, ...] ) 926 | 927 | 在匹配元素集里面的,每个元素旁边插入内容。 928 | 929 | ```js 930 | $('.apple').after('
  • Plum
  • '); 931 | $.html(); 932 | //=>
      933 | //
    • Apple
    • 934 | //
    • Plum
    • 935 | //
    • Orange
    • 936 | //
    • Pear
    • 937 | //
    938 | ``` 939 | 940 | #### .insertAfter( target ) 941 | 942 | 在 target 之后,插入匹配元素集里面的,每个元素。 943 | 944 | ```js 945 | $('
  • Plum
  • ').insertAfter('.apple'); 946 | $.html(); 947 | //=>
      948 | //
    • Apple
    • 949 | //
    • Plum
    • 950 | //
    • Orange
    • 951 | //
    • Pear
    • 952 | //
    953 | ``` 954 | 955 | #### .before( content, [content, ...] ) 956 | 957 | 在匹配元素集里面的,每个元素之前,插入内容。 958 | 959 | ```js 960 | $('.apple').before('
  • Plum
  • '); 961 | $.html(); 962 | //=>
      963 | //
    • Plum
    • 964 | //
    • Apple
    • 965 | //
    • Orange
    • 966 | //
    • Pear
    • 967 | //
    968 | ``` 969 | 970 | #### .insertBefore( target ) 971 | 972 | 在 target 之前,插入匹配元素集里面的,每个元素。 973 | 974 | ```js 975 | $('
  • Plum
  • ').insertBefore('.apple'); 976 | $.html(); 977 | //=>
      978 | //
    • Plum
    • 979 | //
    • Apple
    • 980 | //
    • Orange
    • 981 | //
    • Pear
    • 982 | //
    983 | ``` 984 | 985 | #### .remove( [selector] ) 986 | 987 | 删除 DOM 及其所有子项中的匹配元素集。`selector`过滤要删除的匹配元素集。 988 | 989 | ```js 990 | $('.pear').remove(); 991 | $.html(); 992 | //=>
      993 | //
    • Apple
    • 994 | //
    • Orange
    • 995 | //
    996 | ``` 997 | 998 | #### .replaceWith( content ) 999 | 1000 | 用`content`替换匹配的元素。 1001 | 1002 | ```js 1003 | const plum = $('
  • Plum
  • '); 1004 | $('.pear').replaceWith(plum); 1005 | $.html(); 1006 | //=>
      1007 | //
    • Apple
    • 1008 | //
    • Orange
    • 1009 | //
    • Plum
    • 1010 | //
    1011 | ``` 1012 | 1013 | #### .empty() 1014 | 1015 | 清空元素,删除所有子元素。 1016 | 1017 | ```js 1018 | $('ul').empty(); 1019 | $.html(); 1020 | //=>
      1021 | ``` 1022 | 1023 | #### .html( [htmlString] ) 1024 | 1025 | 从第一个选定元素,获取 html 内容字符串。如果`htmlString`指定了,则每个选定元素的内容,将替换为新内容。 1026 | 1027 | ```js 1028 | $('.orange').html(); 1029 | //=> Orange 1030 | 1031 | $('#fruits') 1032 | .html('
    • Mango
    • ') 1033 | .html(); 1034 | //=>
    • Mango
    • 1035 | ``` 1036 | 1037 | #### .text( [textString] ) 1038 | 1039 | 获取匹配元素集里面,每个元素的文本内容组合,包括它们的后代。如果`textString`指定,则每个选定元素的内容,将替换为新文本内容。 1040 | 1041 | ```js 1042 | $('.orange').text(); 1043 | //=> Orange 1044 | 1045 | $('ul').text(); 1046 | //=> Apple 1047 | // Orange 1048 | // Pear 1049 | ``` 1050 | 1051 | #### .wrap( content ) 1052 | 1053 | 该 `.wrap`函数可以接受,任何能传递给\$()工厂函数的字符串或对象,用来指定 DOM 结构。这个结构可以嵌套几层深,但应该只包含一个 inmost 元素。此结构的副本,会包裹住匹配元素集,每个元素都会进行包装。此方法返回,已改装的原始元素集。 1054 | 1055 | ```js 1056 | const redFruit = $('
      '); 1057 | $('.apple').wrap(redFruit); 1058 | 1059 | //=>
        1060 | //
        1061 | //
      • Apple
      • 1062 | //
        1063 | //
      • Orange
      • 1064 | //
      • Plum
      • 1065 | //
      1066 | 1067 | const healthy = $('
      '); 1068 | $('li').wrap(healthy); 1069 | 1070 | //=>
        1071 | //
        1072 | //
      • Apple
      • 1073 | //
        1074 | //
        1075 | //
      • Orange
      • 1076 | //
        1077 | //
        1078 | //
      • Plum
      • 1079 | //
        1080 | //
      1081 | ``` 1082 | 1083 | #### .css( [propertyName] )
      .css( [ propertyNames] )
      .css( [propertyName], [value] )
      .css( [propertyName], [function] )
      .css( [properties] ) 1084 | 1085 | 获取匹配元素集里面,第一个元素的样式属性值,或为每个匹配元素设置一个或多个 CSS 属性。 1086 | 1087 | ### 渲染 1088 | 1089 | 当您准备好渲染文档时,您可以使用实用函数`html`: 1090 | 1091 | ```js 1092 | $.html(); 1093 | //=>
        1094 | //
      • Apple
      • 1095 | //
      • Orange
      • 1096 | //
      • Pear
      • 1097 | //
      1098 | ``` 1099 | 1100 | 如果要返回 outerHTML,可以使用`$.html(selector)`: 1101 | 1102 | ```js 1103 | $.html('.pear'); 1104 | //=>
    • Pear
    • 1105 | ``` 1106 | 1107 | 默认情况下,`html`会留下一些标签。有时您可能希望呈现有效的 XML 文档。例如,您可以解析以下 XML 代码段: 1108 | 1109 | ```xml 1110 | const $ = cheerio.load(''); 1111 | ``` 1112 | 1113 | ...以 后想要渲染到 XML。为此,您可以使用'xml'实用程序函数: 1114 | 1115 | ```js 1116 | $.xml(); 1117 | //=> 1118 | ``` 1119 | 1120 | 您还可以使用。渲染 Cheerio 对象的文本内容,通过静态方法`text`就行: 1121 | 1122 | ```js 1123 | const $ = cheerio.load('This is content.'); 1124 | $.text(); 1125 | //=> This is content. 1126 | ``` 1127 | 1128 | 可以通过 Cheerio 模块本身,调用该方法 - 确保传递的是节点集合! 1129 | 1130 | ```js 1131 | const $ = cheerio.load('
      This is content.
      '); 1132 | cheerio.text($('div')); 1133 | //=> This is content. 1134 | ``` 1135 | 1136 | ### 杂项 1137 | 1138 | DOM 元素方法,不适合其他任何地方 1139 | 1140 | #### .toArray() 1141 | 1142 | 将 jQuery 集里面包含的所有 DOM 元素,转为数组。 1143 | 1144 | ```js 1145 | $('li').toArray(); 1146 | //=> [ {...}, {...}, {...} ] 1147 | ``` 1148 | 1149 | #### .clone() 1150 | 1151 | 克隆 cheerio 对象。 1152 | 1153 | ```js 1154 | const moreFruit = $('#fruits').clone(); 1155 | ``` 1156 | 1157 | ### 工具箱 1158 | 1159 | #### \$.root 1160 | 1161 | 有时您需要使用顶级根元素。要查询它,您可以使用`$.root()`。 1162 | 1163 | ```js 1164 | $.root() 1165 | .append('
        ') 1166 | .html(); 1167 | //=>
          ...
          1168 | ``` 1169 | 1170 | #### \$.contains( container, contained ) 1171 | 1172 | 检查`contained`DOM 元素是否为`container`DOM 元素的后代。 1173 | 1174 | #### \$.parseHTML( data [, context ][, keepscripts ] ) 1175 | 1176 | 将字符串解析为 DOM 节点数组。该`context`参,数对 Cheerio 没有意义,但它是为了兼容 API 而维护的。 1177 | 1178 | #### \$.load( html[, options ] ) 1179 | 1180 | 加载 HTML。(有关详细信息,请参阅上一节标题为“加载”。) 1181 | 1182 | ### 插件 1183 | 1184 | 一旦加载文档后,您可以扩展原型,或等效`fn`属性,使用自定义插件方法: 1185 | 1186 | ```js 1187 | const $ = cheerio.load('Hello, world!'); 1188 | $.prototype.logHtml = function() { 1189 | console.log(this.html()); 1190 | }; 1191 | 1192 | $('body').logHtml(); // logs "Hello, world!" to the console 1193 | ``` 1194 | 1195 | ### “DOM Node”对象 1196 | 1197 | Cheerio 所制造的对象,与[基于浏览器的 DOM 节点](https://developer.mozilla.org/en-US/docs/Web/API/Node)有许多相似之处。所以,您可以期望它们定义了以下属性: 1198 | 1199 | - `tagName` 1200 | - `parentNode` 1201 | - `previousSibling` 1202 | - `nextSibling` 1203 | - `nodeValue` 1204 | - `firstChild` 1205 | - `childNodes` 1206 | - `lastChild` 1207 | 1208 | ## 视频讲解 1209 | 1210 | 1211 | 1212 | > 这个视频教程是 Nettut 的“如何使用 Node.js 和 jQuery 抓取网页”的后续内容,使用 cheerio 而不是 JSDOM + jQuery。这个视频展示了使用 cheerio 是多么容易,以及 cheerio 比 JSDOM + jQuery 快多少。 1213 | 1214 | ## 贡献者 1215 | 1216 | 这些是贡献者,让 cheerio 成为可能的人: 1217 | 1218 | ``` 1219 | project : cheerio 1220 | repo age : 2 years, 6 months 1221 | active : 285 days 1222 | commits : 762 1223 | files : 36 1224 | authors : 1225 | 293 Matt Mueller 38.5% 1226 | 133 Matthew Mueller 17.5% 1227 | 92 Mike Pennisi 12.1% 1228 | 54 David Chambers 7.1% 1229 | 30 kpdecker 3.9% 1230 | 19 Felix Böhm 2.5% 1231 | 17 fb55 2.2% 1232 | 15 Siddharth Mahendraker 2.0% 1233 | 11 Adam Bretz 1.4% 1234 | 8 Nazar Leush 1.0% 1235 | 7 ironchefpython 0.9% 1236 | 6 Jarno Leppänen 0.8% 1237 | 5 Ben Sheldon 0.7% 1238 | 5 Jos Shepherd 0.7% 1239 | 5 Ryan Schmukler 0.7% 1240 | 5 Steven Vachon 0.7% 1241 | 4 Maciej Adwent 0.5% 1242 | 4 Amir Abu Shareb 0.5% 1243 | 3 jeremy.dentel@brandingbrand.com 0.4% 1244 | 3 Andi Neck 0.4% 1245 | 2 steve 0.3% 1246 | 2 alexbardas 0.3% 1247 | 2 finspin 0.3% 1248 | 2 Ali Farhadi 0.3% 1249 | 2 Chris Khoo 0.3% 1250 | 2 Rob Ashton 0.3% 1251 | 2 Thomas Heymann 0.3% 1252 | 2 Jaro Spisak 0.3% 1253 | 2 Dan Dascalescu 0.3% 1254 | 2 Torstein Thune 0.3% 1255 | 2 Wayne Larsen 0.3% 1256 | 1 Timm Preetz 0.1% 1257 | 1 Xavi 0.1% 1258 | 1 Alex Shaindlin 0.1% 1259 | 1 mattym 0.1% 1260 | 1 Felix Böhm 0.1% 1261 | 1 Farid Neshat 0.1% 1262 | 1 Dmitry Mazuro 0.1% 1263 | 1 Jeremy Hubble 0.1% 1264 | 1 nevermind 0.1% 1265 | 1 Manuel Alabor 0.1% 1266 | 1 Matt Liegey 0.1% 1267 | 1 Chris O'Hara 0.1% 1268 | 1 Michael Holroyd 0.1% 1269 | 1 Michiel De Mey 0.1% 1270 | 1 Ben Atkin 0.1% 1271 | 1 Rich Trott 0.1% 1272 | 1 Rob "Hurricane" Ashton 0.1% 1273 | 1 Robin Gloster 0.1% 1274 | 1 Simon Boudrias 0.1% 1275 | 1 Sindre Sorhus 0.1% 1276 | 1 xiaohwan 0.1% 1277 | ``` 1278 | 1279 | ## Cheerio 在现实世界中 1280 | 1281 | 你在生产中,使用 cheerio 吗?把它添加到[wiki](https://github.com/cheeriojs/cheerio/wiki/Cheerio-in-Production)! 1282 | 1283 | ## 测试 1284 | 1285 | 要运行测试套件,请下载存储库,然后在 cheerio 目录中,运行: 1286 | 1287 | ```shell 1288 | make setup 1289 | make test 1290 | ``` 1291 | 1292 | 这将下载开发包,并运行测试套件。 1293 | 1294 | ## 特别谢谢 1295 | 1296 | 这个库站在一些令人难以置信的开发人员的肩膀上。特别感谢: 1297 | 1298 | **•@FB55 for node-htmlparser2&CSSSelect:**Felix 有编写快速解析引擎的诀窍。他完全重写了@ tautologistic 的`node-htmlparser`和@harry 的`node-soupselect`,从头开始,使他们两个更快,更灵活。没有他的基础工作,Cheerio 是不可能的 1299 | 1300 | **•@jQuery jQuery 团队:**核心 API 是同类产品中最好的,尽管需要处理了,所有浏览器的不一致性,但代码库非常干净且易于理解。cheerio 的大部分实现和文档来自 jQuery。多谢你们。 1301 | 1302 | **•@visionmedia:**这个库的风格,结构,开源“性”,来自于研究 TJ 的风格和使用他的许多库。这个家伙不断推出高质量的库,并且一直非常愿意帮助或回答问题。很摇滚啊, TJ。 1303 | 1304 | ## 执照 1305 | 1306 | MIT 1307 | -------------------------------------------------------------------------------- /en.md: -------------------------------------------------------------------------------- 1 |

          cheerio

          2 | 3 |
          Fast, flexible & lean implementation of core jQuery designed specifically for the server.
          4 | 5 | 22 | 23 |
          24 | 25 | ```js 26 | const cheerio = require('cheerio') 27 | const $ = cheerio.load('

          Hello world

          ') 28 | 29 | $('h2.title').text('Hello there!') 30 | $('h2').addClass('welcome') 31 | 32 | $.html() 33 | //=>

          Hello there!

          34 | ``` 35 | 36 | ## Note 37 | 38 | We are currently working on the 1.0.0 release of cheerio on the `master` branch. The source code for the last published version, `0.22.0`, can be found [here](https://github.com/cheeriojs/cheerio/tree/aa90399c9c02f12432bfff97b8f1c7d8ece7c307). 39 | 40 | ## Installation 41 | `npm install cheerio` 42 | 43 | ## Features 44 | __❤ Familiar syntax:__ 45 | Cheerio implements a subset of core jQuery. Cheerio removes all the DOM inconsistencies and browser cruft from the jQuery library, revealing its truly gorgeous API. 46 | 47 | __ϟ Blazingly fast:__ 48 | Cheerio works with a very simple, consistent DOM model. As a result parsing, manipulating, and rendering are incredibly efficient. Preliminary end-to-end benchmarks suggest that cheerio is about __8x__ faster than JSDOM. 49 | 50 | __❁ Incredibly flexible:__ 51 | Cheerio wraps around @FB55's forgiving [htmlparser2](https://github.com/fb55/htmlparser2/). Cheerio can parse nearly any HTML or XML document. 52 | 53 | ## Cheerio is not a web browser 54 | 55 | Cheerio parses markup and provides an API for traversing/manipulating the resulting data structure. It does not interpret the result as a web browser does. Specifically, it does *not* produce a visual rendering, apply CSS, load external resources, or execute JavaScript. If your use case requires any of this functionality, you should consider projects like [PhantomJS](http://phantomjs.org/) or [JSDom](https://github.com/tmpvar/jsdom). 56 | 57 | ## API 58 | 59 | ### Table of contents 60 | 61 |
          62 | Selectors 63 | 64 | - [$( selector, [context], [root] )](#-selector-context-root-) 65 |
          66 |
          67 | Attributes 68 | 69 | - [.attr( name, value )](#attr-name-value-) 70 | - [.prop( name, value )](#prop-name-value-) 71 | - [.data( name, value )](#data-name-value-) 72 | - [.val( [value] )](#val-value-) 73 | - [.removeAttr( name )](#removeattr-name-) 74 | - [.hasClass( className )](#hasclass-classname-) 75 | - [.addClass( className )](#addclass-classname-) 76 | - [.removeClass( [className] )](#removeclass-classname-) 77 | - [.toggleClass( className, [switch] )](#toggleclass-classname-switch-) 78 | - [.is( selector )](#is-selector-) 79 | - [.is( element )](#is-element-) 80 | - [.is( selection )](#is-selection-) 81 | - [.is( function(index) )](#is-functionindex-) 82 |
          83 |
          84 | Forms 85 | 86 | - [.serialize()](#serialize) 87 | - [.serializeArray()](#serializearray) 88 |
          89 |
          90 | Traversing 91 | 92 | - [.find(selector)](#findselector) 93 | - [.find(selection)](#findselection) 94 | - [.find(node)](#findnode) 95 | - [.parent([selector])](#parentselector) 96 | - [.parents([selector])](#parentsselector) 97 | - [.parentsUntil([selector][,filter])](#parentsuntilselectorfilter) 98 | - [.closest(selector)](#closestselector) 99 | - [.next([selector])](#nextselector) 100 | - [.nextAll([selector])](#nextallselector) 101 | - [.nextUntil([selector], [filter])](#nextuntilselector-filter) 102 | - [.prev([selector])](#prevselector) 103 | - [.prevAll([selector])](#prevallselector) 104 | - [.prevUntil([selector], [filter])](#prevuntilselector-filter) 105 | - [.slice( start, [end] )](#slice-start-end-) 106 | - [.siblings([selector])](#siblingsselector) 107 | - [.children([selector])](#childrenselector) 108 | - [.contents()](#contents) 109 | - [.each( function(index, element) )](#each-functionindex-element-) 110 | - [.map( function(index, element) )](#map-functionindex-element-) 111 | - [.filter( selector )
          112 | .filter( selection )
          113 | .filter( element )
          114 | .filter( function(index, element) )](#filter-selector---filter-selection---filter-element---filter-functionindex-element-) 115 | - [.not( selector )
          116 | .not( selection )
          117 | .not( element )
          118 | .not( function(index, elem) )](#not-selector---not-selection---not-element---not-functionindex-elem-) 119 | - [.has( selector )
          120 | .has( element )](#has-selector---has-element-) 121 | - [.first()](#first) 122 | - [.last()](#last) 123 | - [.eq( i )](#eq-i-) 124 | - [.get( [i] )](#get-i-) 125 | - [.index()](#index) 126 | - [.index( selector )](#index-selector-) 127 | - [.index( nodeOrSelection )](#index-nodeorselection-) 128 | - [.end()](#end) 129 | - [.add( selector [, context] )](#add-selector--context-) 130 | - [.add( element )](#add-element-) 131 | - [.add( elements )](#add-elements-) 132 | - [.add( html )](#add-html-) 133 | - [.add( selection )](#add-selection-) 134 | - [.addBack( [filter] )](#addback-filter-) 135 |
          136 |
          137 | Manipulation 138 | 139 | - [.append( content, [content, ...] )](#append-content-content--) 140 | - [.appendTo( target )](#appendto-target-) 141 | - [.prepend( content, [content, ...] )](#prepend-content-content--) 142 | - [.prependTo( target )](#prependto-target-) 143 | - [.after( content, [content, ...] )](#after-content-content--) 144 | - [.insertAfter( target )](#insertafter-target-) 145 | - [.before( content, [content, ...] )](#before-content-content--) 146 | - [.insertBefore( target )](#insertbefore-target-) 147 | - [.remove( [selector] )](#remove-selector-) 148 | - [.replaceWith( content )](#replacewith-content-) 149 | - [.empty()](#empty) 150 | - [.html( [htmlString] )](#html-htmlstring-) 151 | - [.text( [textString] )](#text-textstring-) 152 | - [.wrap( content )](#wrap-content-) 153 | - [.css( [propertName] )
          154 | .css( [ propertyNames] )
          155 | .css( [propertyName], [value] )
          156 | .css( [propertName], [function] )
          157 | .css( [properties] )](#css-propertname---css--propertynames---css-propertyname-value---css-propertname-function---css-properties-) 158 |
          159 | 160 | ### Markup example we'll be using: 161 | 162 | ```html 163 |
            164 |
          • Apple
          • 165 |
          • Orange
          • 166 |
          • Pear
          • 167 |
          168 | ``` 169 | 170 | This is the HTML markup we will be using in all of the API examples. 171 | 172 | ### Loading 173 | First you need to load in the HTML. This step in jQuery is implicit, since jQuery operates on the one, baked-in DOM. With Cheerio, we need to pass in the HTML document. 174 | 175 | This is the _preferred_ method: 176 | 177 | ```js 178 | const cheerio = require('cheerio'); 179 | const $ = cheerio.load('
            ...
          '); 180 | ``` 181 | 182 | Optionally, you can also load in the HTML by passing the string as the context: 183 | 184 | ```js 185 | const $ = require('cheerio'); 186 | $('ul', '
            ...
          '); 187 | ``` 188 | 189 | Or as the root: 190 | 191 | ```js 192 | const $ = require('cheerio'); 193 | $('li', 'ul', '
            ...
          '); 194 | ``` 195 | 196 | You can also pass an extra object to `.load()` if you need to modify any 197 | of the default parsing options: 198 | 199 | ```js 200 | const $ = cheerio.load('
            ...
          ', { 201 | normalizeWhitespace: true, 202 | xmlMode: true 203 | }); 204 | ``` 205 | 206 | These parsing options are taken directly from [htmlparser2](https://github.com/fb55/htmlparser2/wiki/Parser-options), therefore any options that can be used in `htmlparser2` are valid in cheerio as well. The default options are: 207 | 208 | ```js 209 | { 210 | withDomLvl1: true, 211 | normalizeWhitespace: false, 212 | xmlMode: false, 213 | decodeEntities: true 214 | } 215 | 216 | ``` 217 | 218 | For a full list of options and their effects, see [this](https://github.com/fb55/DomHandler) and 219 | [htmlparser2's options](https://github.com/fb55/htmlparser2/wiki/Parser-options). 220 | 221 | ### Selectors 222 | 223 | Cheerio's selector implementation is nearly identical to jQuery's, so the API is very similar. 224 | 225 | #### $( selector, [context], [root] ) 226 | `selector` searches within the `context` scope which searches within the `root` scope. `selector` and `context` can be a string expression, DOM Element, array of DOM elements, or cheerio object. `root` is typically the HTML document string. 227 | 228 | This selector method is the starting point for traversing and manipulating the document. Like jQuery, it's the primary method for selecting elements in the document, but unlike jQuery it's built on top of the CSSSelect library, which implements most of the Sizzle selectors. 229 | 230 | ```js 231 | $('.apple', '#fruits').text() 232 | //=> Apple 233 | 234 | $('ul .pear').attr('class') 235 | //=> pear 236 | 237 | $('li[class=orange]').html() 238 | //=> Orange 239 | ``` 240 | 241 | ##### XML Namespaces 242 | You can select with XML Namespaces but [due to the CSS specification](https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#attribute-selectors), the colon (`:`) needs to be escaped for the selector to be valid. 243 | 244 | ```js 245 | $('[xml\\:id="main"'); 246 | ``` 247 | 248 | ### Attributes 249 | Methods for getting and modifying attributes. 250 | 251 | #### .attr( name, value ) 252 | Method for getting and setting attributes. Gets the attribute value for only the first element in the matched set. If you set an attribute's value to `null`, you remove that attribute. You may also pass a `map` and `function` like jQuery. 253 | 254 | ```js 255 | $('ul').attr('id') 256 | //=> fruits 257 | 258 | $('.apple').attr('id', 'favorite').html() 259 | //=>
        • Apple
        • 260 | ``` 261 | 262 | > See http://api.jquery.com/attr/ for more information 263 | 264 | #### .prop( name, value ) 265 | Method for getting and setting properties. Gets the property value for only the first element in the matched set. 266 | 267 | ```js 268 | $('input[type="checkbox"]').prop('checked') 269 | //=> false 270 | 271 | $('input[type="checkbox"]').prop('checked', true).val() 272 | //=> ok 273 | ``` 274 | 275 | > See http://api.jquery.com/prop/ for more information 276 | 277 | #### .data( name, value ) 278 | Method for getting and setting data attributes. Gets or sets the data attribute value for only the first element in the matched set. 279 | 280 | ```js 281 | $('
          ').data() 282 | //=> { appleColor: 'red' } 283 | 284 | $('
          ').data('apple-color') 285 | //=> 'red' 286 | 287 | const apple = $('.apple').data('kind', 'mac') 288 | apple.data('kind') 289 | //=> 'mac' 290 | ``` 291 | 292 | > See http://api.jquery.com/data/ for more information 293 | 294 | #### .val( [value] ) 295 | Method for getting and setting the value of input, select, and textarea. Note: Support for `map`, and `function` has not been added yet. 296 | 297 | ```js 298 | $('input[type="text"]').val() 299 | //=> input_text 300 | 301 | $('input[type="text"]').val('test').html() 302 | //=> 303 | ``` 304 | 305 | #### .removeAttr( name ) 306 | Method for removing attributes by `name`. 307 | 308 | ```js 309 | $('.pear').removeAttr('class').html() 310 | //=>
        • Pear
        • 311 | ``` 312 | 313 | #### .hasClass( className ) 314 | Check to see if *any* of the matched elements have the given `className`. 315 | 316 | ```js 317 | $('.pear').hasClass('pear') 318 | //=> true 319 | 320 | $('apple').hasClass('fruit') 321 | //=> false 322 | 323 | $('li').hasClass('pear') 324 | //=> true 325 | ``` 326 | 327 | #### .addClass( className ) 328 | Adds class(es) to all of the matched elements. Also accepts a `function` like jQuery. 329 | 330 | ```js 331 | $('.pear').addClass('fruit').html() 332 | //=>
        • Pear
        • 333 | 334 | $('.apple').addClass('fruit red').html() 335 | //=>
        • Apple
        • 336 | ``` 337 | 338 | > See http://api.jquery.com/addClass/ for more information. 339 | 340 | #### .removeClass( [className] ) 341 | Removes one or more space-separated classes from the selected elements. If no `className` is defined, all classes will be removed. Also accepts a `function` like jQuery. 342 | 343 | ```js 344 | $('.pear').removeClass('pear').html() 345 | //=>
        • Pear
        • 346 | 347 | $('.apple').addClass('red').removeClass().html() 348 | //=>
        • Apple
        • 349 | ``` 350 | 351 | > See http://api.jquery.com/removeClass/ for more information. 352 | 353 | #### .toggleClass( className, [switch] ) 354 | Add or remove class(es) from the matched elements, depending on either the class's presence or the value of the switch argument. Also accepts a `function` like jQuery. 355 | 356 | ```js 357 | $('.apple.green').toggleClass('fruit green red').html() 358 | //=>
        • Apple
        • 359 | 360 | $('.apple.green').toggleClass('fruit green red', true).html() 361 | //=>
        • Apple
        • 362 | ``` 363 | 364 | > See http://api.jquery.com/toggleClass/ for more information. 365 | 366 | #### .is( selector ) 367 | #### .is( element ) 368 | #### .is( selection ) 369 | #### .is( function(index) ) 370 | Checks the current list of elements and returns `true` if _any_ of the elements match the selector. If using an element or Cheerio selection, returns `true` if _any_ of the elements match. If using a predicate function, the function is executed in the context of the selected element, so `this` refers to the current element. 371 | 372 | ### Forms 373 | 374 | #### .serialize() 375 | 376 | Encodes a set of form elements as a URL query string. 377 | 378 | ```js 379 | $('
          ').serialize() 380 | //=> foo=bar&foo=qux 381 | ``` 382 | 383 | #### .serializeArray() 384 | 385 | Encode a set of form elements as an array of names and values. 386 | 387 | ```js 388 | $('
          ').serializeArray() 389 | //=> [ { name: 'foo', value: 'bar' } ] 390 | ``` 391 | 392 | ### Traversing 393 | 394 | #### .find(selector) 395 | #### .find(selection) 396 | #### .find(node) 397 | Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element. 398 | 399 | ```js 400 | $('#fruits').find('li').length 401 | //=> 3 402 | $('#fruits').find($('.apple')).length 403 | //=> 1 404 | ``` 405 | 406 | #### .parent([selector]) 407 | Get the parent of each element in the current set of matched elements, optionally filtered by a selector. 408 | 409 | ```js 410 | $('.pear').parent().attr('id') 411 | //=> fruits 412 | ``` 413 | 414 | #### .parents([selector]) 415 | Get a set of parents filtered by `selector` of each element in the current set of match elements. 416 | ```js 417 | $('.orange').parents().length 418 | // => 2 419 | $('.orange').parents('#fruits').length 420 | // => 1 421 | ``` 422 | 423 | #### .parentsUntil([selector][,filter]) 424 | Get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector, DOM node, or cheerio object. 425 | ```js 426 | $('.orange').parentsUntil('#food').length 427 | // => 1 428 | ``` 429 | 430 | #### .closest(selector) 431 | For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. 432 | 433 | ```js 434 | $('.orange').closest() 435 | // => [] 436 | $('.orange').closest('.apple') 437 | // => [] 438 | $('.orange').closest('li') 439 | // => [
        • Orange
        • ] 440 | $('.orange').closest('#fruits') 441 | // => [
            ...
          ] 442 | ``` 443 | 444 | #### .next([selector]) 445 | Gets the next sibling of the first selected element, optionally filtered by a selector. 446 | 447 | ```js 448 | $('.apple').next().hasClass('orange') 449 | //=> true 450 | ``` 451 | 452 | #### .nextAll([selector]) 453 | Gets all the following siblings of the first selected element, optionally filtered by a selector. 454 | 455 | ```js 456 | $('.apple').nextAll() 457 | //=> [
        • Orange
        • ,
        • Pear
        • ] 458 | $('.apple').nextAll('.orange') 459 | //=> [
        • Orange
        • ] 460 | ``` 461 | 462 | #### .nextUntil([selector], [filter]) 463 | Gets all the following siblings up to but not including the element matched by the selector, optionally filtered by another selector. 464 | 465 | ```js 466 | $('.apple').nextUntil('.pear') 467 | //=> [
        • Orange
        • ] 468 | ``` 469 | 470 | #### .prev([selector]) 471 | Gets the previous sibling of the first selected element optionally filtered by a selector. 472 | 473 | ```js 474 | $('.orange').prev().hasClass('apple') 475 | //=> true 476 | ``` 477 | 478 | #### .prevAll([selector]) 479 | Gets all the preceding siblings of the first selected element, optionally filtered by a selector. 480 | 481 | ```js 482 | $('.pear').prevAll() 483 | //=> [
        • Orange
        • ,
        • Apple
        • ] 484 | $('.pear').prevAll('.orange') 485 | //=> [
        • Orange
        • ] 486 | ``` 487 | 488 | #### .prevUntil([selector], [filter]) 489 | Gets all the preceding siblings up to but not including the element matched by the selector, optionally filtered by another selector. 490 | 491 | ```js 492 | $('.pear').prevUntil('.apple') 493 | //=> [
        • Orange
        • ] 494 | ``` 495 | 496 | #### .slice( start, [end] ) 497 | Gets the elements matching the specified range 498 | 499 | ```js 500 | $('li').slice(1).eq(0).text() 501 | //=> 'Orange' 502 | 503 | $('li').slice(1, 2).length 504 | //=> 1 505 | ``` 506 | 507 | #### .siblings([selector]) 508 | Gets the first selected element's siblings, excluding itself. 509 | 510 | ```js 511 | $('.pear').siblings().length 512 | //=> 2 513 | 514 | $('.pear').siblings('.orange').length 515 | //=> 1 516 | 517 | ``` 518 | 519 | #### .children([selector]) 520 | Gets the children of the first selected element. 521 | 522 | ```js 523 | $('#fruits').children().length 524 | //=> 3 525 | 526 | $('#fruits').children('.pear').text() 527 | //=> Pear 528 | ``` 529 | 530 | #### .contents() 531 | Gets the children of each element in the set of matched elements, including text and comment nodes. 532 | 533 | ```js 534 | $('#fruits').contents().length 535 | //=> 3 536 | ``` 537 | 538 | #### .each( function(index, element) ) 539 | Iterates over a cheerio object, executing a function for each matched element. 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`. To break out of the `each` loop early, return with `false`. 540 | 541 | ```js 542 | const fruits = []; 543 | 544 | $('li').each(function(i, elem) { 545 | fruits[i] = $(this).text(); 546 | }); 547 | 548 | fruits.join(', '); 549 | //=> Apple, Orange, Pear 550 | ``` 551 | 552 | #### .map( function(index, element) ) 553 | Pass each element in the current matched set through a function, producing a new Cheerio object containing the return values. The function can return an individual data item or an array of data items to be inserted into the resulting set. If an array is returned, the elements inside the array are inserted into the set. If the function returns null or undefined, no element will be inserted. 554 | 555 | ```js 556 | $('li').map(function(i, el) { 557 | // this === el 558 | return $(this).text(); 559 | }).get().join(' '); 560 | //=> "apple orange pear" 561 | ``` 562 | 563 | #### .filter( selector )
          .filter( selection )
          .filter( element )
          .filter( function(index, element) ) 564 | 565 | Iterates over a cheerio object, reducing the set of selector elements to those that match the selector or pass the function's test. When a Cheerio selection is specified, return only the elements contained in that selection. When an element is specified, return only that element (if it is contained in the original selection). If using the function method, the function is executed in the context of the selected element, so `this` refers to the current element. 566 | 567 | Selector: 568 | 569 | ```js 570 | $('li').filter('.orange').attr('class'); 571 | //=> orange 572 | ``` 573 | 574 | Function: 575 | 576 | ```js 577 | $('li').filter(function(i, el) { 578 | // this === el 579 | return $(this).attr('class') === 'orange'; 580 | }).attr('class') 581 | //=> orange 582 | ``` 583 | 584 | #### .not( selector )
          .not( selection )
          .not( element )
          .not( function(index, elem) ) 585 | 586 | Remove elements from the set of matched elements. Given a jQuery object that represents a set of DOM elements, the `.not()` method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; the elements that don't match the selector will be included in the result. The `.not()` method can take a function as its argument in the same way that `.filter()` does. Elements for which the function returns true are excluded from the filtered set; all other elements are included. 587 | 588 | Selector: 589 | 590 | ```js 591 | $('li').not('.apple').length; 592 | //=> 2 593 | ``` 594 | 595 | Function: 596 | 597 | ```js 598 | $('li').not(function(i, el) { 599 | // this === el 600 | return $(this).attr('class') === 'orange'; 601 | }).length; 602 | //=> 2 603 | ``` 604 | 605 | #### .has( selector )
          .has( element ) 606 | 607 | Filters the set of matched elements to only those which have the given DOM element as a descendant or which have a descendant that matches the given selector. Equivalent to `.filter(':has(selector)')`. 608 | 609 | Selector: 610 | 611 | ```js 612 | $('ul').has('.pear').attr('id'); 613 | //=> fruits 614 | ``` 615 | 616 | Element: 617 | 618 | ```js 619 | $('ul').has($('.pear')[0]).attr('id'); 620 | //=> fruits 621 | ``` 622 | 623 | #### .first() 624 | Will select the first element of a cheerio object 625 | 626 | ```js 627 | $('#fruits').children().first().text() 628 | //=> Apple 629 | ``` 630 | 631 | #### .last() 632 | Will select the last element of a cheerio object 633 | 634 | ```js 635 | $('#fruits').children().last().text() 636 | //=> Pear 637 | ``` 638 | 639 | #### .eq( i ) 640 | Reduce the set of matched elements to the one at the specified index. Use `.eq(-i)` to count backwards from the last selected element. 641 | 642 | ```js 643 | $('li').eq(0).text() 644 | //=> Apple 645 | 646 | $('li').eq(-1).text() 647 | //=> Pear 648 | ``` 649 | 650 | #### .get( [i] ) 651 | 652 | Retrieve the DOM elements matched by the Cheerio object. If an index is specified, retrieve one of the elements matched by the Cheerio object: 653 | 654 | ```js 655 | $('li').get(0).tagName 656 | //=> li 657 | ``` 658 | 659 | If no index is specified, retrieve all elements matched by the Cheerio object: 660 | 661 | ```js 662 | $('li').get().length 663 | //=> 3 664 | ``` 665 | 666 | #### .index() 667 | #### .index( selector ) 668 | #### .index( nodeOrSelection ) 669 | 670 | Search for a given element from among the matched elements. 671 | 672 | ```js 673 | $('.pear').index() 674 | //=> 2 675 | $('.orange').index('li') 676 | //=> 1 677 | $('.apple').index($('#fruit, li')) 678 | //=> 1 679 | ``` 680 | 681 | #### .end() 682 | End the most recent filtering operation in the current chain and return the set of matched elements to its previous state. 683 | 684 | ```js 685 | $('li').eq(0).end().length 686 | //=> 3 687 | ``` 688 | 689 | #### .add( selector [, context] ) 690 | #### .add( element ) 691 | #### .add( elements ) 692 | #### .add( html ) 693 | #### .add( selection ) 694 | Add elements to the set of matched elements. 695 | 696 | ```js 697 | $('.apple').add('.orange').length 698 | //=> 2 699 | ``` 700 | 701 | #### .addBack( [filter] ) 702 | 703 | Add the previous set of elements on the stack to the current set, optionally filtered by a selector. 704 | 705 | ```js 706 | $('li').eq(0).addBack('.orange').length 707 | //=> 2 708 | ``` 709 | 710 | ### Manipulation 711 | Methods for modifying the DOM structure. 712 | 713 | #### .append( content, [content, ...] ) 714 | Inserts content as the *last* child of each of the selected elements. 715 | 716 | ```js 717 | $('ul').append('
        • Plum
        • ') 718 | $.html() 719 | //=>
            720 | //
          • Apple
          • 721 | //
          • Orange
          • 722 | //
          • Pear
          • 723 | //
          • Plum
          • 724 | //
          725 | ``` 726 | 727 | #### .appendTo( target ) 728 | Insert every element in the set of matched elements to the end of the target. 729 | 730 | ```js 731 | $('
        • Plum
        • ').appendTo('#fruits') 732 | $.html() 733 | //=>
            734 | //
          • Apple
          • 735 | //
          • Orange
          • 736 | //
          • Pear
          • 737 | //
          • Plum
          • 738 | //
          739 | ``` 740 | 741 | #### .prepend( content, [content, ...] ) 742 | Inserts content as the *first* child of each of the selected elements. 743 | 744 | ```js 745 | $('ul').prepend('
        • Plum
        • ') 746 | $.html() 747 | //=>
            748 | //
          • Plum
          • 749 | //
          • Apple
          • 750 | //
          • Orange
          • 751 | //
          • Pear
          • 752 | //
          753 | ``` 754 | 755 | #### .prependTo( target ) 756 | Insert every element in the set of matched elements to the beginning of the target. 757 | 758 | ```js 759 | $('
        • Plum
        • ').prependTo('#fruits') 760 | $.html() 761 | //=>
            762 | //
          • Plum
          • 763 | //
          • Apple
          • 764 | //
          • Orange
          • 765 | //
          • Pear
          • 766 | //
          767 | ``` 768 | 769 | #### .after( content, [content, ...] ) 770 | Insert content next to each element in the set of matched elements. 771 | 772 | ```js 773 | $('.apple').after('
        • Plum
        • ') 774 | $.html() 775 | //=>
            776 | //
          • Apple
          • 777 | //
          • Plum
          • 778 | //
          • Orange
          • 779 | //
          • Pear
          • 780 | //
          781 | ``` 782 | 783 | #### .insertAfter( target ) 784 | Insert every element in the set of matched elements after the target. 785 | 786 | ```js 787 | $('
        • Plum
        • ').insertAfter('.apple') 788 | $.html() 789 | //=>
            790 | //
          • Apple
          • 791 | //
          • Plum
          • 792 | //
          • Orange
          • 793 | //
          • Pear
          • 794 | //
          795 | ``` 796 | 797 | #### .before( content, [content, ...] ) 798 | Insert content previous to each element in the set of matched elements. 799 | 800 | ```js 801 | $('.apple').before('
        • Plum
        • ') 802 | $.html() 803 | //=>
            804 | //
          • Plum
          • 805 | //
          • Apple
          • 806 | //
          • Orange
          • 807 | //
          • Pear
          • 808 | //
          809 | ``` 810 | 811 | #### .insertBefore( target ) 812 | Insert every element in the set of matched elements before the target. 813 | 814 | ```js 815 | $('
        • Plum
        • ').insertBefore('.apple') 816 | $.html() 817 | //=>
            818 | //
          • Plum
          • 819 | //
          • Apple
          • 820 | //
          • Orange
          • 821 | //
          • Pear
          • 822 | //
          823 | ``` 824 | 825 | #### .remove( [selector] ) 826 | Removes the set of matched elements from the DOM and all their children. `selector` filters the set of matched elements to be removed. 827 | 828 | ```js 829 | $('.pear').remove() 830 | $.html() 831 | //=>
            832 | //
          • Apple
          • 833 | //
          • Orange
          • 834 | //
          835 | ``` 836 | 837 | #### .replaceWith( content ) 838 | Replaces matched elements with `content`. 839 | 840 | ```js 841 | const plum = $('
        • Plum
        • ') 842 | $('.pear').replaceWith(plum) 843 | $.html() 844 | //=>
            845 | //
          • Apple
          • 846 | //
          • Orange
          • 847 | //
          • Plum
          • 848 | //
          849 | ``` 850 | 851 | #### .empty() 852 | Empties an element, removing all its children. 853 | 854 | ```js 855 | $('ul').empty() 856 | $.html() 857 | //=>
            858 | ``` 859 | 860 | #### .html( [htmlString] ) 861 | Gets an html content string from the first selected element. If `htmlString` is specified, each selected element's content is replaced by the new content. 862 | 863 | ```js 864 | $('.orange').html() 865 | //=> Orange 866 | 867 | $('#fruits').html('
          • Mango
          • ').html() 868 | //=>
          • Mango
          • 869 | ``` 870 | 871 | #### .text( [textString] ) 872 | Get the combined text contents of each element in the set of matched elements, including their descendants. If `textString` is specified, each selected element's content is replaced by the new text content. 873 | 874 | ```js 875 | $('.orange').text() 876 | //=> Orange 877 | 878 | $('ul').text() 879 | //=> Apple 880 | // Orange 881 | // Pear 882 | ``` 883 | 884 | #### .wrap( content ) 885 | The .wrap() function can take any string or object that could be passed to the $() factory function to specify a DOM structure. This structure may be nested several levels deep, but should contain only one inmost element. A copy of this structure will be wrapped around each of the elements in the set of matched elements. This method returns the original set of elements for chaining purposes. 886 | 887 | ```js 888 | const redFruit = $('
            ') 889 | $('.apple').wrap(redFruit) 890 | 891 | //=>
              892 | //
              893 | //
            • Apple
            • 894 | //
              895 | //
            • Orange
            • 896 | //
            • Plum
            • 897 | //
            898 | 899 | const healthy = $('
            ') 900 | $('li').wrap(healthy) 901 | 902 | //=>
              903 | //
              904 | //
            • Apple
            • 905 | //
              906 | //
              907 | //
            • Orange
            • 908 | //
              909 | //
              910 | //
            • Plum
            • 911 | //
              912 | //
            913 | ``` 914 | 915 | #### .css( [propertyName] )
            .css( [ propertyNames] )
            .css( [propertyName], [value] )
            .css( [propertyName], [function] )
            .css( [properties] ) 916 | 917 | Get the value of a style property for the first element in the set of matched elements or set one or more CSS properties for every matched element. 918 | 919 | ### Rendering 920 | When you're ready to render the document, you can use the `html` utility function: 921 | 922 | ```js 923 | $.html() 924 | //=>
              925 | //
            • Apple
            • 926 | //
            • Orange
            • 927 | //
            • Pear
            • 928 | //
            929 | ``` 930 | 931 | If you want to return the outerHTML you can use `$.html(selector)`: 932 | 933 | ```js 934 | $.html('.pear') 935 | //=>
          • Pear
          • 936 | ``` 937 | 938 | 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: 939 | 940 | ```xml 941 | const $ = cheerio.load(''); 942 | ``` 943 | 944 | ... and later want to render to XML. To do this, you can use the 'xml' utility function: 945 | 946 | ```js 947 | $.xml() 948 | //=> 949 | ``` 950 | 951 | You may also render the text content of a Cheerio object using the `text` static method: 952 | 953 | ```js 954 | const $ = cheerio.load('This is content.') 955 | $.text() 956 | //=> This is content. 957 | ``` 958 | 959 | The method may be called on the Cheerio module itself--be sure to pass a collection of nodes! 960 | 961 | ```js 962 | const $ = cheerio.load('
            This is content.
            ') 963 | cheerio.text($('div')) 964 | //=> This is content. 965 | ``` 966 | 967 | ### Miscellaneous 968 | DOM element methods that don't fit anywhere else 969 | 970 | #### .toArray() 971 | Retrieve all the DOM elements contained in the jQuery set as an array. 972 | 973 | ```js 974 | $('li').toArray() 975 | //=> [ {...}, {...}, {...} ] 976 | ``` 977 | 978 | #### .clone() #### 979 | Clone the cheerio object. 980 | 981 | ```js 982 | const moreFruit = $('#fruits').clone() 983 | ``` 984 | 985 | ### Utilities 986 | 987 | #### $.root 988 | 989 | Sometimes you need to work with the top-level root element. To query it, you can use `$.root()`. 990 | 991 | ```js 992 | $.root().append('
              ').html(); 993 | //=>
                ...
                994 | ``` 995 | 996 | #### $.contains( container, contained ) 997 | Checks to see if the `contained` DOM element is a descendant of the `container` DOM element. 998 | 999 | #### $.parseHTML( data [, context ] [, keepScripts ] ) 1000 | Parses a string into an array of DOM nodes. The `context` argument has no meaning for Cheerio, but it is maintained for API compatibility. 1001 | 1002 | #### $.load( html[, options ] ) 1003 | Load in the HTML. (See the previous section titled "Loading" for more information.) 1004 | 1005 | ### Plugins 1006 | 1007 | Once you have loaded a document, you may extend the prototype or the equivalent `fn` property with custom plugin methods: 1008 | 1009 | ```js 1010 | const $ = cheerio.load('Hello, world!'); 1011 | $.prototype.logHtml = function() { 1012 | console.log(this.html()); 1013 | }; 1014 | 1015 | $('body').logHtml(); // logs "Hello, world!" to the console 1016 | ``` 1017 | 1018 | ### The "DOM Node" object 1019 | 1020 | Cheerio collections are made up of objects that bear some resemblance to [browser-based DOM nodes](https://developer.mozilla.org/en-US/docs/Web/API/Node). You can expect them to define the following properties: 1021 | 1022 | - `tagName` 1023 | - `parentNode` 1024 | - `previousSibling` 1025 | - `nextSibling` 1026 | - `nodeValue` 1027 | - `firstChild` 1028 | - `childNodes` 1029 | - `lastChild` 1030 | 1031 | ## Screencasts 1032 | 1033 | http://vimeo.com/31950192 1034 | 1035 | > This video tutorial is a follow-up to Nettut's "How to Scrape Web Pages with Node.js and jQuery", using cheerio instead of JSDOM + jQuery. This video shows how easy it is to use cheerio and how much faster cheerio is than JSDOM + jQuery. 1036 | 1037 | ## Contributors 1038 | 1039 | These are some of the contributors that have made cheerio possible: 1040 | 1041 | ``` 1042 | project : cheerio 1043 | repo age : 2 years, 6 months 1044 | active : 285 days 1045 | commits : 762 1046 | files : 36 1047 | authors : 1048 | 293 Matt Mueller 38.5% 1049 | 133 Matthew Mueller 17.5% 1050 | 92 Mike Pennisi 12.1% 1051 | 54 David Chambers 7.1% 1052 | 30 kpdecker 3.9% 1053 | 19 Felix Böhm 2.5% 1054 | 17 fb55 2.2% 1055 | 15 Siddharth Mahendraker 2.0% 1056 | 11 Adam Bretz 1.4% 1057 | 8 Nazar Leush 1.0% 1058 | 7 ironchefpython 0.9% 1059 | 6 Jarno Leppänen 0.8% 1060 | 5 Ben Sheldon 0.7% 1061 | 5 Jos Shepherd 0.7% 1062 | 5 Ryan Schmukler 0.7% 1063 | 5 Steven Vachon 0.7% 1064 | 4 Maciej Adwent 0.5% 1065 | 4 Amir Abu Shareb 0.5% 1066 | 3 jeremy.dentel@brandingbrand.com 0.4% 1067 | 3 Andi Neck 0.4% 1068 | 2 steve 0.3% 1069 | 2 alexbardas 0.3% 1070 | 2 finspin 0.3% 1071 | 2 Ali Farhadi 0.3% 1072 | 2 Chris Khoo 0.3% 1073 | 2 Rob Ashton 0.3% 1074 | 2 Thomas Heymann 0.3% 1075 | 2 Jaro Spisak 0.3% 1076 | 2 Dan Dascalescu 0.3% 1077 | 2 Torstein Thune 0.3% 1078 | 2 Wayne Larsen 0.3% 1079 | 1 Timm Preetz 0.1% 1080 | 1 Xavi 0.1% 1081 | 1 Alex Shaindlin 0.1% 1082 | 1 mattym 0.1% 1083 | 1 Felix Böhm 0.1% 1084 | 1 Farid Neshat 0.1% 1085 | 1 Dmitry Mazuro 0.1% 1086 | 1 Jeremy Hubble 0.1% 1087 | 1 nevermind 0.1% 1088 | 1 Manuel Alabor 0.1% 1089 | 1 Matt Liegey 0.1% 1090 | 1 Chris O'Hara 0.1% 1091 | 1 Michael Holroyd 0.1% 1092 | 1 Michiel De Mey 0.1% 1093 | 1 Ben Atkin 0.1% 1094 | 1 Rich Trott 0.1% 1095 | 1 Rob "Hurricane" Ashton 0.1% 1096 | 1 Robin Gloster 0.1% 1097 | 1 Simon Boudrias 0.1% 1098 | 1 Sindre Sorhus 0.1% 1099 | 1 xiaohwan 0.1% 1100 | ``` 1101 | 1102 | ## Cheerio in the real world 1103 | 1104 | Are you using cheerio in production? Add it to the [wiki](https://github.com/cheeriojs/cheerio/wiki/Cheerio-in-Production)! 1105 | 1106 | ## Testing 1107 | 1108 | To run the test suite, download the repository, then within the cheerio directory, run: 1109 | 1110 | ```shell 1111 | make setup 1112 | make test 1113 | ``` 1114 | 1115 | This will download the development packages and run the test suite. 1116 | 1117 | ## Special Thanks 1118 | 1119 | This library stands on the shoulders of some incredible developers. A special thanks to: 1120 | 1121 | __• @FB55 for node-htmlparser2 & CSSSelect:__ 1122 | Felix has a knack for writing speedy parsing engines. He completely re-wrote both @tautologistic's `node-htmlparser` and @harry's `node-soupselect` from the ground up, making both of them much faster and more flexible. Cheerio would not be possible without his foundational work 1123 | 1124 | __• @jQuery team for jQuery:__ 1125 | The core API is the best of its class and despite dealing with all the browser inconsistencies the code base is extremely clean and easy to follow. Much of cheerio's implementation and documentation is from jQuery. Thanks guys. 1126 | 1127 | __• @visionmedia:__ 1128 | The style, the structure, the open-source"-ness" of this library comes from studying TJ's style and using many of his libraries. This dude consistently pumps out high-quality libraries and has always been more than willing to help or answer questions. You rock TJ. 1129 | 1130 | ## License 1131 | 1132 | MIT 1133 | --------------------------------------------------------------------------------