以 https://www.80s.la/ 為例,抓取 2015 年電影列表頁分頁,進入詳情頁提取標題與迅雷下載鏈接,存入 MySQL。
/movie/list/-2015----p{頁碼} 列表頁/movie/數字 模式,提取 <title> 與 thunder:// 鏈接LinkedHashMap 去重並保持順序private Map<String, String> crawlLinks(String host, Map<String, Boolean> toVisit) {
Map<String, String> videoLinks = new LinkedHashMap<>();
Map<String, Boolean> newLinks = new LinkedHashMap<>();
for (Map.Entry<String, Boolean> e : toVisit.entrySet()) {
if (e.getValue()) continue; // 已訪問
String url = e.getKey();
// HTTP GET 請求...
// 列表頁:提取所有 <a href="...">,過濾後加入 newLinks
// 詳情頁:正則提取 title 與 thunder 鏈接,存入 videoLinks
toVisit.put(url, true);
}
if (!newLinks.isEmpty()) {
toVisit.putAll(newLinks);
videoLinks.putAll(crawlLinks(host, toVisit)); // 遞歸
}
return videoLinks;
}
try (Connection conn = JDBCUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO movie(MovieName, MovieLink) VALUES(?,?)")) {
for (Map.Entry<String, String> e : videoLinks.entrySet()) {
ps.setString(1, e.getKey());
ps.setString(2, e.getValue());
ps.executeUpdate();
}
}
<a href="([^"\s]*)"([^\s]+).*?</title>(thunder:[^"]+).*thunder[Rr][Ee][Ss][Tt]itle="[^"]*"Thread.sleep(1000) 避免被封