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

Java 網頁爬蟲實戰:抓取百度音樂/金書網資料存入 MySQL(含正則解析、Servlet 排程、DBUtils 封裝)

     編輯:Java 程式設計入門

專案架構


webTools.IOTOWeb      ← 百度音樂榜單爬蟲
webTools.GetBook      ← 金書網書籍資訊爬蟲
dbTools.DBTools       ← JDBC 封裝(PreparedStatement + 連線管理)
controller.TestURL    ← Servlet 觸發百度爬蟲
controller.TestBook   ← Servlet 觸發金書爬蟲(含重試邏輯)

核心爬蟲流程(以百度音樂為例)

  1. getHtmlContent(url):URL.openStream() + BufferedReader 讀取原始 HTML(指定 GB2312 編碼)
  2. getMainContent():正則擷取 <table class="list">...</table> 區塊
  3. getLink():擷取每行 <td> 完整標籤
  4. getSongName() / getPerson() / getHref():細部正則提取歌名、歌手、連結
  5. outTag():replaceAll("<.*?>", "") 移除 HTML 標籤
  6. DBTools.update():參數化 SQL 寫入 MySQL

關鍵代碼片段

1. 正則解析(簡化版)

// 主表格
String tableRegex = "<table width=\"100%\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"list\">(.*?)</table>";
// 每行 td
String tdRegex = "<td[^>]*>[\\(]*<a[^>]*href=(\"([^\"]*)\"|'([^']*)'|([^\\s>]*))[^>]*>(.*?)[\\)]*[\\s]*</td>";
// 歌名
String songRegex = "<a[^>]*href=(\"([^\"]*)\"|'([^']*)'|([^\\s>]*))[^>]*>(.*?)</a>\\s";
// 歌手(括號內)
String personRegex = "\\(<a[^>]*href=(\"([^\"]*)\"|'([^']*)'|([^\\s>]*))[^>]*>(.*?)\\)";
// 連結
String hrefRegex = "href=(\"([^\"]*)\"|'([^']*)'|([^\\s>]*))\"";

2. DBTools 封裝(改良版:try-with-resources)

public class DBTools {
    private static final String URL = "jdbc:mysql://localhost:3306/TestURL?useSSL=false&serverTimezone=Asia/Taipei";
    private static final String USER = "root";
    private static final String PASS = "zhuyi";

    static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (Exception e) { throw new RuntimeException(e); } }

    public void update(String sql, List params) {
        try (Connection conn = DriverManager.getConnection(URL, USER, PASS);
             PreparedStatement ps = conn.prepareStatement(sql)) {
            for (int i = 0; i < params.size(); i++) ps.setObject(i + 1, params.get(i));
            ps.executeUpdate();
        } catch (SQLException e) { throw new RuntimeException(e); }
    }

    public List> query(String sql, List params) {
        List> rows = new ArrayList<>();
        try (Connection conn = DriverManager.getConnection(URL, USER, PASS);
             PreparedStatement ps = conn.prepareStatement(sql)) {
            for (int i = 0; i < params.size(); i++) ps.setObject(i + 1, params.get(i));
            try (ResultSet rs = ps.executeQuery()) {
                ResultSetMetaData md = rs.getMetaData();
                int cols = md.getColumnCount();
                while (rs.next()) {
                    List row = new ArrayList<>(cols);
                    for (int i = 1; i <= cols; i++) row.add(rs.getString(i));
                    rows.add(row);
                }
            }
        } catch (SQLException e) { throw new RuntimeException(e); }
        return rows;
    }
}


3. Servlet 排程觸發(含指數退避重試)


@WebServlet("/crawl/baidu")
public class CrawlBaiduServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        new Thread(() -> {
            try {
                new IOTOWeb().getFromBaiduMap3("https://list.mp3.baidu.com/topso/mp3topsong.html?id=1?top2");
                log("百度爬蟲完成");
            } catch (Exception e) {
                log("百度爬蟲失敗", e);
            }
        }).start();
        resp.getWriter().write("爬蟲已在背景啟動");
    }
}

金書網爬蟲差異

  • 目標:https://www.golden-book.com/booksinfo/12/{id}.html
  • 解析:<span class="style15">書名</span>
  • 重試機制:捕獲例外 → i++ → 遞迴呼叫 doPost/doGet(⚠️ 易造成堆疊溢位,建議改用迴圈)

現代化重構建議

層面現狀建議升級
HTTP ClientURL.openStream()Apache HttpClient 5 / OkHttp / Java 11 HttpClient
HTML 解析RegexJsoup (CSS Selector) - 穩健、可維護
資料庫手寫 JDBCHikariCP + MyBatis / JdbcTemplate / JPA
排程Servlet + ThreadSpring @Scheduled / Quartz / Spring Batch
編碼處理硬編碼 GB2312自動偵測 Content-Type / HTML meta charset
錯誤處理printStackTrace / 遞迴重試統一例外處理、指數退避、死信隊列、監控告警

法律與道德提醒

  • 請遵守目標網站 robots.txt、服務條款與爬蟲頻率限制。
  • 大量請求請加入 User-Agent、Referer、隨機延遲、IP 代理池。
  • 僅供技術學習,勿用於商業資料竊取。

總結

本範例展示了「HTTP 取得 → 正則解析 → JDBC 入庫 → Servlet 觸發」的完整爬蟲鏈路。理解基礎原理後,強烈建議採用現代化框架重構,提升穩定性、可維護性與合規性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved