看到心儀小說卻無離線下載功能?動手寫個 Java 爬蟲吧!本文展示如何使用 Jsoup 這款強大的 HTML 解析庫,配合基本 I/O,實作一個「輸入目錄頁 URL → 自動遍歷所有章節 → 清洗內容 → 合併存為 TXT」的完整小說下載器。代碼簡潔、邏輯清晰,適合作為爬蟲入門實戰與後續擴展基礎。
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.16.1</version> </dependency> package com.example.novel; import java.io.*; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; public class NovelCrawler { public static void main(String[] args) { try { File output = new File("D:/novel/無限崩壞.txt"); createFile(output); downloadNovel(output); } catch (Exception e) { e.printStackTrace(); } } private static void downloadNovel(File file) throws IOException, InterruptedException { // 寫入書名/作者資訊 append(file, buildHeader("無限崩壞", "啪啪啪狂魔")); // 章節 URL 模板:{pattern} 為章節 ID String urlTemplate = "https://www.example.com/View/12/12653/{pattern}.html"; // 實際需替換為真實站點 // 章節 ID 範圍 (需人工確認或解析目錄頁獲取) for (int id = 5850686; id <= 5945501; id++) { try { String url = urlTemplate.replace("{pattern}", String.valueOf(id)); String content = fetchChapter(url); append(file, content); // 禮貌延遲,避免被封 IP Thread.sleep(100); } catch (Exception e) { System.err.println("章節 " + id + " 下載失敗: " + e.getMessage()); // 記錄失敗 ID 可選 } } } private static String fetchChapter(String url) throws IOException { Document doc = Jsoup.connect(url) .userAgent("Mozilla/5.0") .timeout(10000) .get(); // 1. 取得標題 Elements titleEl = doc.select("#title"); String title = titleEl.text(); // 2. 取得正文內容 Elements contentEl = doc.select(".text p"); // 3. 清洗:移除廣告、腳本、內聯樣式、超連結 contentEl.select("font, script, ins, a, style").remove(); // 4. 組裝:標題 + 內容 (段落換行) String body = contentEl.html() .replaceAll("<p>", "") .replaceAll("</p>", System.lineSeparator()) .replaceAll("<br>", System.lineSeparator()) .replaceAll(" ", " ") .replaceAll("<!--.*?-->", ""); return title + System.lineSeparator() + body + System.lineSeparator() + System.lineSeparator(); } private static String buildHeader(String book, String author) { String line = "--------------------------------------------------"; return line + System.lineSeparator() + "書名:" + book + System.lineSeparator() + "作者:" + author + System.lineSeparator() + "來源:Java 爬蟲自動下載" + System.lineSeparator() + line + System.lineSeparator() + System.lineSeparator(); } private static void createFile(File file) throws IOException { file.getParentFile().mkdirs(); file.createNewFile(); } private static void append(File file, String content) throws IOException { try (FileWriter fw = new FileWriter(file, true)) { fw.write(content); } } } | 環節 | 技術/方法 | 說明 |
|---|---|---|
| HTML 解析 | Jsoup.connect().get() | 自動處理重定向、Cookie、編碼,支援 CSS 選擇器 |
| 元素選取 | doc.select("#title"), doc.select(".text p") | CSS 選擇器語法,極其靈活 |
| 內容清洗 | elements.select("font, script, a").remove() | 移除廣告標籤、腳本、超連結,保留純文本 |
| 實體轉義 | .html() 保留標籤 → replaceAll 處理 | 將
|
| 檔案寫入 | FileWriter(file, true) 追加模式 | 避免大字串佔用記憶體,邊抓邊存 |
| 禮貌爬蟲 | Thread.sleep(100) | 降低請求頻率,尊重目標站點資源 |
ExecutorService + Semaphore 限流 (如 5 並發),大幅提速。robots.txt、網站服務條款、版權法,僅供個人學習研究使用。Jsoup.connect(url).charset("GBK").get() 指定編碼,或檢查 Response Header Content-Type。 、< 實體?.text() 會自動轉義,若需保留換行結構用 .html() 配合手動 replace。new FileWriter(file, true)),切勿在記憶體拼接全書字串。本文展示了「Jsoup + 追加寫入 + 禮貌延遲」的極簡爬蟲核心模式。幾十行代碼即可實現自動化下載,展現了 Java 生態處理網路資源的便利性。但請記住:技術無罪,用途有責。爬蟲僅供個人學習、離線閱讀使用,嚴禁商業化分發、大規模抓取影響他人服務、侵犯版權。願你在代碼世界裡自由遨遊,也尊重創作者的勞動成果。