撰寫一個 Java 類別,輸入目標網址,自動下載 HTML 內容並解析出所有 <a href=...> 超連結,支援自動偵測網頁編碼。
HtmlParserpublic class HtmlParser {
private String htmlUrl; // 目標網址
private ArrayList<String> hrefList; // 解析結果集合
private String charSet; // 網頁編碼
public HtmlParser(String htmlUrl) { ... }
public ArrayList<String> getHrefList() throws IOException { ... }
private void parser() throws IOException { ... }
private String getCharset(String contentType) { ... }
private String getHref(String line) { ... }
}
parser()private void parser() throws IOException {
URL url = new URL(htmlUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
// 從 Content-Type 標頭取得編碼
String contentType = conn.getContentType();
charSet = getCharset(contentType);
// 以正確編碼讀取內容
InputStreamReader isr = new InputStreamReader(conn.getInputStream(), charSet);
BufferedReader br = new BufferedReader(isr);
String line, href;
while ((line = br.readLine()) != null) {
href = getHref(line);
if (href != null) hrefList.add(href);
}
}
getCharset()private String getCharset(String str) {
Pattern pattern = Pattern.compile("charset=.*");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
return matcher.group(0).split("charset=")[1];
}
return null; // 若無指定編碼,依賴 JVM 預設
}
getHref()private String getHref(String str) {
// 簡易正則:匹配完整 <a href=...>...</a> 標籤
Pattern pattern = Pattern.compile("<a href=.*</a>");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
return matcher.group(0);
}
return null;
}
public static void main(String[] args) throws IOException {
HtmlParser parser = new HtmlParser("https://news.163.com/");
ArrayList<String> links = parser.getHrefList();
for (String link : links) {
System.out.println(link);
}
}
| 限制 | 改進建議 |
|---|---|
| 逐行讀取可能斷開跨行標籤 | 改用完整 HTML 字串或 Jsoup 等專用解析器 |
| 正則表達式脆弱,難以應對複雜 HTML | 採用 DOM/SAX 解析器(如 Jsoup, HtmlCleaner) |
| 僅抓取 href 屬性完整標籤,未解析純 URL | 進一步提取 href="..." 內容並轉為絕對路徑 |
| 無錯誤重試、連線逾時、User-Agent 設定 | 加入健壯的 HTTP 客戶端設定(HttpClient/OkHttp) |
| 單執行緒,效率低 | 引入多執行緒或非同步框架並發抓取 |
// 依賴:org.jsoup:jsoup:1.17.2
public List<String> fetchLinksWithJsoup(String url) throws IOException {
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0")
.timeout(10000)
.get();
Elements links = doc.select("a[href]");
List<String> result = new ArrayList<>();
for (Element link : links) {
result.add(link.attr("abs:href")); // 直接取得絕對路徑
}
return result;
}
本範例示範了 Java 原生 API 實作簡易網頁爬蟲的基本流程:建立連線、偵測編碼、讀取內容、正則解析。雖然可運作,但生產環境強烈建議使用成熟的 HTML 解析庫(如 Jsoup)以獲得更佳的穩定性與功能性。