Node.js爬蟲 CheerioJS ?輕量級解析、操作和渲染HTML及XML文檔

簡介

? 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 配置

類型默認值描述
scriptingEnabledfalse是否啟用腳本
xmlModetrue啟用 htmlparser2 的 XML 模式
decodeEntitiestrue解碼 HTML 實體。
withStartIndicesfalse為節點添加一個startIndex屬性
withEndIndicesfalse為節點添加一個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!

?更多用法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88533.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88533.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88533.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為運維工程師面試題(英語試題,內部資料)

華為運維工程師面試題(英語試題,內部資料) 一、英文自我介紹,重點突出自己運維經驗(10分) 二、短語翻譯(英譯中)(15*3分=45分) 1. Data is a collection of un-organized facts, which can include words, numb ers, images, and sounds. 1. 數據是未經組織的事…

【趙渝強老師】使用mydumper備份MySQL

MySQL在備份方面包含了自身的mysqldump工具&#xff0c;但其只支持單線程工作&#xff0c;這就使得它無法迅速的備份數據。而mydumper作為一個實用工具&#xff0c;能夠良好支持多線程工作&#xff0c;這使得它在處理速度方面十倍于傳統的mysqldump。其特征之一是在處理過程中需…

華為云 Flexus+DeepSeek 征文|華為云單機部署 Dify-LLM 開發平臺全流程指南【服務部署、模型配置、知識庫構建全流程】

華為云 FlexusDeepSeek 征文&#xff5c;華為云單機部署 Dify-LLM 開發平臺全流程指南【服務部署、模型配置、知識庫構建全流程】 文章目錄 華為云 FlexusDeepSeek 征文&#xff5c;華為云單機部署 Dify-LLM 開發平臺全流程指南【服務部署、模型配置、知識庫構建全流程】前言1、…

?通義萬相 2.1(Wan2.1)環境搭建指南:基于 CUDA 12.4 + Python 3.11 + PyTorch 2.5.1 GPU加速實戰

&#x1f680;【超詳細】基于 CUDA 12.4 Python 3.11 構建 Wan2.1 項目的集成推理環境&#xff08;含 PyTorch 2.5.1 GPU 安裝教程&#xff09; 本文將一步一步帶你搭建一個可用于構建和運行 Wan2.1 的深度學習環境&#xff0c;完全兼容 CUDA 12.4&#xff0c;并基于官方鏡像 …

PROFIBUS DP轉ETHERNET/IP在熱電項目中的創新應用

在熱電項目中&#xff0c;多種設備的高效協同是保障能源穩定供應的關鍵。PROFIBUS DP與ETHERNET/IP兩種工業通信協議因特性不同而應用場景各異。通過協議轉換技術實現JH-PB-EIP疆鴻智能PROFIBUS DP轉ETHERNET/IP&#xff0c;可整合西門子PLC與電力儀表、變頻器等設備&#xff0…

精準把脈 MySQL 性能!xk6-sql 并發測試深度指南

在數據庫性能測試領域&#xff0c;xk6-sql憑借其強大的功能和靈活性&#xff0c;成為眾多開發者和測試人員的得力工具。它能夠模擬高并發場景&#xff0c;精準測試數據庫在不同負載下的性能表現。然而&#xff0c;在一些網絡受限的環境中&#xff0c;實現xk6-sql的離線安裝以及…

【文件】Linux 內核優化實戰 - fs.inotify.max_user_instances

目錄 一、參數作用與原理1. 核心功能2. 應用場景 二、默認值與影響因素1. 默認配置2. 影響因素 三、調整方法與示例1. 查看當前值2. 臨時修改&#xff08;生效至系統重啟&#xff09;3. 永久修改&#xff08;修改配置文件&#xff09;4. 合理值建議 四、常見報錯與解決方案1. 報…

c++系列之特殊類的設計

&#x1f497; &#x1f497; 博客:小怡同學 &#x1f497; &#x1f497; 個人簡介:編程小萌新 &#x1f497; &#x1f497; 如果博客對大家有用的話&#xff0c;請點贊關注再收藏 &#x1f31e; 僅在堆上創建對象的類 將類的構造函數&#xff0c;拷貝構造私有,防止在棧上生…

SpringBoot的國際化

國際化&#xff08;internationalization&#xff09;是設計容易適應不同區域要求的產品的一種方式。它要求從產品中抽離所有地域語言元素。換言之&#xff0c;應用程序的功能和代碼設計考慮了在不同地區運行的需要。開發這樣的程序的過程&#xff0c;就稱為國際化。 那么當我…

prometheus+grafana+Linux監控

prometheusgrafanaLinux監控 環境說明 操作前提&#xff1a; 先去搭建Docker部署prometheusgrafana...這篇文章的系統 Docker部署prometheusgrafana...的參考文章&#xff1a; Docker部署prometheusgrafana…-CSDN博客 Linux部署docker參考文章&#xff1a; 02-Docker安裝_doc…

文檔處理控件Aspose.Words教程:在.NET中將多頁文檔轉換為單個圖像

在Aspose.Words for .NET 25.6版本中&#xff0c;我們引入了一項新功能&#xff0c;允許您將多頁文檔導出為單個光柵圖像。當您需要將文檔作為單個可視文件共享或顯示時&#xff0c;此功能非常有用。 Aspose.Words for .NET 25.6 的新功能 在 25.6 版之前&#xff0c;將多頁文…

vuex4.0用法

VUEX 狀態管理&#xff0c;多個組件有共享數據的時候&#xff0c;就叫狀態管理 什么情況下會用到vuex , 如果你不知道vuex的情況也能完成你的需求&#xff0c;就說你的項目中不需要用到狀態管理。 組件層級比較復雜的時候&#xff0c;還是用組件傳值的方式來傳值&#xff0c;…

2025.6.24總結

今天發生了兩件事&#xff0c;這每件事情都足以影響我的工作狀態。 1.團隊中有人要轉崗 這算是最讓我有些小震驚的事件了。我不明白&#xff0c;那個同事干得好好的&#xff0c;為啥會轉崗&#xff0c;為啥會被調到其他團隊。雖然團隊有正編&#xff0c;有od,但我自始自終覺得…

狀態模式詳解

概述 結構設計類似責任鏈模式&#xff0c;但是在各個狀態進行遍歷的過程中&#xff0c;更注重的是條件的判斷&#xff0c;只有符合條件的狀態才能正常匹配進行處理。條件不成功的會立即切換到下一個狀態。 有限狀態機 狀態機一般指的是有限狀態機&#xff08;FSM&#xff1a…

Lua 調試(Debug)

Lua 調試(Debug) 引言 Lua 是一種輕量級的編程語言&#xff0c;廣泛應用于游戲開發、嵌入式系統、腳本編寫等領域。在 Lua 開發過程中&#xff0c;調試是確保程序正確運行的重要環節。本文將詳細介紹 Lua 調試的基本方法、常用工具以及調試技巧&#xff0c;幫助開發者提高編程…

Windows安裝Emscripten?/emsdk(成功)

安裝git安裝python 不要自行下載版本&#xff0c;先卸載其他版本的python。 使用管理員打開cmd&#xff0c;輸入python3&#xff0c;直接跳轉到應用商店&#xff0c;安裝即可。 為什么一定要這么安裝&#xff1f;好像是跟路徑有關。 下載emsdk git clone https://github.c…

AI網頁部署在本地_windows

用bolt.new寫了一個網頁&#xff0c;下載ZIP至本地 以下是在 Windows 上本地運行你用 Node.js 搭建的網頁服務&#xff0c;并在瀏覽器中訪問的常見流程&#xff1a; 1、安裝 Node.js 訪問官網 Node.js — Run JavaScript Everywhere &#xff0c;下載適合 Windows 的 LTS 版本…

Linux sudo命令

sudo是一個常用的Linux命令&#xff0c;用于以超級用戶的權限執行命令。下面是對sudo命令的介紹&#xff1a; sudo命令的作用&#xff1a; sudo允許普通用戶以超級用戶&#xff08;root&#xff09;的身份執行特定命令或訪問特定文件。它提供了一種安全且可控制的方式&#xf…

郵件合并----批量從excel表中導出數據到word中

文章目錄 前言一、操作流程1. 打開word&#xff0c;開始郵件合并->郵件合并分布向導2. 開始郵件合并&#xff0c;一共6步3. 選擇全部&#xff0c;點擊確認&#xff0c;即可生成Excel表中244條記錄&#xff0c;也就是244頁。 總結 前言 涉及到將學生的姓名、學號、檔案編號、…

活動安排貪心算法

輸入說明 n??????—— 活動數量 s[1…n]??— 第 i 個活動的開始時間 (start) f[1…n]??— 第 i 個活動的結束時間 (finish) 前置要求&#xff1a;數組已按 f 從小到大排好序 &#xff08;若沒排&#xff0c;先調用 sortByFinishTime()&#xff0c;復雜度 O(n log …