簡介
? CheerioJS ? 是一個專為 Node.js 設計的輕量級庫,用于解析、操作和渲染 HTML 及 XML 文檔,語法類似 Jquery。
安裝
npm install cheerio
示例
const cheerio = require("cheerio");const html = `
<html><head><title>Example</title></head><body><h1>Hello, world!</h1></body>
</html>
`;const $ = cheerio.load(html);console.log($("h1").text()); // 輸出: Hello, world!
加載文檔
load
解析 HTML 或 XML 文檔的最基本方式
import * as cheerio from "cheerio";const html = `
<html><head><title>Example</title></head><body><div class="container"><div class="item">React.js</div><div class="item">Vue.js</div><div class="item">Angular.js</div></div></body>
</html>
`;const $ = cheerio.load(html);
console.log(111, $("div.container .item:first-child").text()); // 輸出: React.js
loadBuffer
解析存儲文檔內容的 buffer 類型數據結構
import * as cheerio from "cheerio";
import * as fs from "fs";const buffer = fs.readFileSync("document.html");
const $ = cheerio.loadBuffer(buffer);
console.log(111, $("div.container .item:first-child").text()); // 輸出: React.js
fromURL
從 URL 加載文檔
import * as cheerio from "cheerio";const $ = await cheerio.fromURL("https://example.com");
選擇元素
Cheerio 允許用戶使用 CSS 選擇器 從文檔中選擇元素。方法語法與 jquery 基本一樣。
$("p"); // 選擇所有 <p> 元素
$("p.item"); // 選擇所有 class 為 item 的 <p> 元素
$("p.item:first-child"); // 選擇第一個 class 為 item 的 <p> 元素
$("p.item:last-child"); // 選擇最后一個 class 為 item 的 <p> 元素
$(".selected"); // 選擇所有 class 為 selected 的元素
$("[data-selected=true]"); // 選擇所有 data-selected 屬性為 true 的元素
$('[xml\\:id="main"'); // 選擇所有 xml:id 屬性為 main 的元素
$("p.selected"); // 選擇所有 class 為 selected 的 <p> 元素
$("div p"); // 選擇所有 <div> 元素中的 <p> 元素
$("div > p"); // 選擇所有直接子元素為 <p> 的 <div> 元素
$('p:contains("hello")'); // 選擇所有包含 "hello" 文字的 <p> 元素
find 查找元素
import * as cheerio from "cheerio";const html = `
<html><head><title>Example</title></head><body><div class="container"><div class="item">React.js</div><div class="item">Vue.js</div><div class="item">Angular.js</div></div></body>
</html>
`;const $ = cheerio.load(html);
const items = $(".container").find(".item");
items.each((index, element) => {console.log($(element).text());
});
children 查找子元素
import * as cheerio from "cheerio";const html = `
<html><head><title>Example</title></head><body><div class="container"><div class="item">React.js</div><div class="item">Vue.js</div><div class="item">Angular.js</div></div></body>
</html>
`;const $ = cheerio.load(html);
const items = $(".container").children(".item");
items.each((index, element) => {console.log($(element).text());
});
find vs children 區別
- find 方法會遞歸查找所有符合條件的元素,包括子元素、子元素的子元素等。
- children 方法只會查找直接子元素,不會查找子元素的子元素。
contents 查找所有子節點
所有子元素,包括文本和注釋節點。
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const items = $(".container").contents();
console.log(items.length); // 輸出: 7
parent 查找父元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const parent = $(".item").parent();
console.log(parent.prop("class")); // 輸出: container
parents 查找所有父元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const parents = $(".item").parents();
parents.each((index, element) => {console.log($(element).prop("tagName"));
});
// 輸出:DIV、BODY、HTML
parentsUntil 查找父元素直到指定元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const parents = $(".item").parentsUntil("body");
parents.each((index, element) => {console.log($(element).prop("tagName"));
});
closest 查找最近的父元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const result = $(".item").closest(".container");
console.log(result.prop("class")); // 輸出: container
next, prev 查找下一個或上一個兄弟元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const next = $(".item:first-child").next();
console.log(next.text()); // 輸出: 2const prev = $(".item:last-child").prev();
console.log(prev.text()); // 輸出: 3
nextAll, prevAll 查找所有下一個或上一個兄弟元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const nextAll = $(".item:first-child").nextAll();
nextAll.each((index, element) => {console.log($(element).text());
});
// 輸出: 2、3const prevAll = $(".item:last-child").prevAll();
prevAll.each((index, element) => {console.log($(element).text());
});
// 輸出: 1、2
siblings 查找所有兄弟元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const siblings = $(".item:first-child").siblings(); // 輸出: 2、3
nextUntil, prevUntil 查找下一個或上一個兄弟元素直到指定元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const nextUntil = $(".item:first-child").nextUntil(".item:last-child");
nextUntil.each((index, element) => {console.log($(element).text());
});
// 輸出: 2const prevUntil = $(".item:last-child").prevUntil(".item:first-child");
prevUntil.each((index, element) => {console.log($(element).text()
})
// 輸出: 3
eq 查找指定索引的元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const result = $(".item").eq(1);
console.log(result.text()); // 輸出: 2
filter 查找符合條件的元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item book">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const result = $(".item").filter(".book");
console.log(result.text()); // 輸出: 2
not 查找不符合條件的元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item book">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const result = $(".item").not(".book");
result.each((index, element) => {console.log($(element).text());
});
// 輸出: 1、3
has 查找包含指定子元素的元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item book"><b>2</b></div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const result = $(".item").has("b");
console.log(result.length); // 輸出: 1
first, last 查找第一個或最后一個元素
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);const first = $(".item").first();
console.log(first.text()); // 輸出: 1const last = $(".item").last();
console.log(last.text()); // 輸出: 3
操作元素
attr 獲取或設置屬性
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item">2</div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const result = $(".item").attr("class");
console.log(result); // 輸出: item$(".img").attr("src", "imgUrl");
console.log($(".img").attr("src")); // 輸出: imgUrl
class 屬性
$("div").addClass("new-class");
$("div").removeClass("old-class");
$("div").toggleClass("toggle-class");
text 獲取或設置文本內容
$("div").text("new text");
console.log($("div").text()); // 輸出: new text
html 獲取或設置 HTML 內容
$("div").html("<p>new html</p>");
console.log($("div").html()); // 輸出: <p>new html</p>
append, prepend 在元素內部追加或前置內容
$(".item").append("<p>append content</p>");
$(".item").prepend("<p>prepend content</p>");
after, before 在元素外部追加或前置內容
$(".item").after("<p>after content</p>");
$(".item").before("<p>before content</p>");
insertAfter, insertBefore 在元素外部追加或前置內容
$("<p>insertAfter content</p>").insertAfter("item");
$("<p>insertBefore content</p>").insertBefore("item");
prependTo, appendTo 在元素內部追加或前置內容
$("<p>prependTo content</p").prependTo(".item");
$("<p>appendTo content</p").appendTo(".item");
wrap, wrapInner 在元素外部包裹內容
$("div").wrap("<div class='wrapper'></div>");
$("div").wrapInner("<div class='wrapper'></div>");
unwrap 移除包裹的元素
$("div").unwrap();
replaceWith 替換元素
$("div").replaceWith("<p>new content</p>");
empty 清空元素內容
$("div").empty();
remove 移除元素
$("div").remove();
更多用法
extract
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item book"><b>2</b></div><div class="item">3</div></div>`;
const $ = cheerio.load(html);
const data = $.extract({book: ".book",
});
console.log(data); // 輸出: {"book": "\n 2\n "}
Configuring 配置
類型 | 默認值 | 描述 |
scriptingEnabled | false | 是否啟用腳本 |
xmlMode | true | 啟用 htmlparser2 的 XML 模式 |
decodeEntities | true | 解碼 HTML 實體。 |
withStartIndices | false | 為節點添加一個startIndex 屬性 |
withEndIndices | false | 為節點添加一個endIndex 屬性 |
Extending 擴展
自定義選擇器
const html = `<div class="container"><div class="item">1</div><div class="item book"><b>2</b></div><div class="item">3</div></div>`;const $ = cheerio.load(html, {pseudos: {book: "div.book",},
});
console.log($(":book").text()); // 2
自定義方法
import * as cheerio from "cheerio";const html = `<div class="container"><div class="item">1</div><div class="item book"><b>2</b></div><div class="item">3</div></div>`;const $ = cheerio.load(html);
$.prototype.myFunction = function () {return "Hello, World!";
};console.log($(".container").myFunction()); // 輸出: Hello, World!
?更多用法