首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 爬蟲利器 Jsoup 詳解:靜態頁解析、選擇器語法、反爬應對與動態渲染局限

     編輯:Java 相關知識

Jsoup 核心能力

  • 解析 HTML:字符串、URL、本地文件 → Document 對象 (DOM 樹)。
  • 強大選擇器:CSS Selector (類 jQuery)、DOM 遍歷、XPath (需額外庫)。
  • 數據提取/操作:元素屬性、文本、HTML、插入刪除節點。
  • 輸出整理:doc.html() 獲取格式化 HTML,doc.outerHtml() 含自身。

快速開始


// 1. 從 URL 獲取 (自動處理重定向、Cookie)
Document doc = Jsoup.connect("https://example.com")
    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120")
    .timeout(10000)
    .get();

// 2. 從字符串解析
Document doc = Jsoup.parse(htmlString, "https://base.uri/");

// 3. 從文件解析
Document doc = Jsoup.parse(new File("page.html"), "UTF-8", "https://base.uri/");

選擇器語法速查 (doc.select("selector"))

實戰:百度首頁提取「新聞」「地圖」鏈接


Document doc = Jsoup.connect("https://www.baidu.com").get();
// 定位導航欄容器
Element nav = doc.select("#u1").first();
if (nav != null) {
    Elements links = nav.select("a.mnav"); // class=mnav 的 a 標簽
    for (Element a : links) {
        System.out.println(a.text() + " -> " + a.attr("abs:href")); // abs: 絕對路徑
    }
}
/* 輸出:
新聞 -> https://news.baidu.com
地圖 -> https://map.baidu.com
...
*/

提取「手機百度」二維碼區域文本


Element qr = doc.select("#qrcode .qrcode-text").first();
if (qr != null) {
    String title = qr.select("b").text(); // "手機百度"
    System.out.println(title);
}

局限:動態渲染頁面

Jsoup 不執行 JavaScript。若數據由 AJAX/Vue/React 動態渲染,Jsoup 只能拿到初始 HTML 模板。

解決方案:

  1. 分析網絡請求:F12 Network 找到真實 API,直接調用 (返回 JSON),再用 Jackson/Gson 解析。
  2. Headless 瀏覽器:Selenium + ChromeDriver、Playwright、Puppeteer (Node) 真實執行 JS 渲染後再提取。
  3. 渲染服務:Prerender.io、Rendertron 等中間件預渲染返回靜態 HTML。

反爬應對技巧

  • 設置合理 User-Agent、Referer、Cookie。
  • 請求間隔隨機化 (Thread.sleep(random))。
  • 使用代理 IP 池輪換。
  • 處理驗證碼:OCR 識別或人工打碼平台。
  • 遵守 robots.txt、Crawl-Delay,合法合規爬取。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
選擇器含義示例
tag標簽名div, a
.classCSS 類.content
#idID#main
[attr]屬性存在[href]
[attr=value]屬性等值[type=submit]
[attr^=value]屬性以值開頭[href^=https]
[attr$=value]屬性以值結尾[src$=.png]
[attr*=value]屬性包含值[class*=item]
parent > child直接子元素ul > li
ancestor descendant後代元素.sidebar a
sibling + sibling相鄰兄弟h2 + p
:eq(n)索引等於 ntr:eq(0) (首行)
:lt(n)索引小於 nli:lt(3) (前三)
:contains(text)文本包含div:contains(錯誤)