Java爬蟲翻頁

TechSynapse發表於2024-07-09

編寫一個Java爬蟲以進行翻頁通常涉及到使用HTTP客戶端(如Apache HttpClient或OkHttp)來傳送請求,解析HTML頁面(如使用Jsoup庫),以及處理分頁邏輯(如透過URL引數或頁面內的連結進行翻頁)。

1. 使用Jsoup和Apache HttpClient的Java爬蟲示例

以下是一個使用Jsoup和Apache HttpClient的Java爬蟲示例,該爬蟲從一個假設的部落格網站抓取文章標題,該網站具有分頁功能(例如,透過URL中的page=引數控制)。

首先,請確保在專案的pom.xml檔案中新增必要的依賴項(如果我們使用的是Maven):

<dependencies>  
    <dependency>  
        <groupId>org.jsoup</groupId>  
        <artifactId>jsoup</artifactId>  
        <version>1.14.3</version>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.httpcomponents</groupId>  
        <artifactId>httpclient</artifactId>  
        <version>4.5.13</version>  
    </dependency>  
</dependencies>

接下來是爬蟲的實現程式碼:

import org.apache.http.client.methods.CloseableHttpResponse;  
import org.apache.http.client.methods.HttpGet;  
import org.apache.http.impl.client.CloseableHttpClient;  
import org.apache.http.impl.client.HttpClients;  
import org.apache.http.util.EntityUtils;  
import org.jsoup.Jsoup;  
import org.jsoup.nodes.Document;  
import org.jsoup.nodes.Element;  
import org.jsoup.select.Elements;  
  
public class BlogSpider {  
  
    private static final String BASE_URL = "http://example.com/blog?page=";  
  
    public static void main(String[] args) {  
        int maxPages = 5; // 假設我們只爬取前5頁  
  
        for (int i = 1; i <= maxPages; i++) {  
            String url = BASE_URL + i;  
            System.out.println("Fetching page: " + url);  
            fetchAndParsePage(url);  
        }  
    }  
  
    private static void fetchAndParsePage(String url) {  
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {  
            HttpGet request = new HttpGet(url);  
            try (CloseableHttpResponse response = httpClient.execute(request)) {  
                if (response.getStatusLine().getStatusCode() == 200) {  
                    String html = EntityUtils.toString(response.getEntity(), "UTF-8");  
                    Document doc = Jsoup.parse(html);  
  
                    // 假設每個文章標題都在<h2>標籤內  
                    Elements articleTitles = doc.select("h2.post-title"); // 可能需要根據實際情況調整選擇器  
                    for (Element title : articleTitles) {  
                        System.out.println(title.text());  
                    }  
                }  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

程式碼解釋:

(1)依賴項:我們使用Jsoup來解析HTML,使用Apache HttpClient來傳送HTTP請求。

(2)基礎URL:設定要爬取的網站的URL基礎部分,這裡假設分頁透過URL中的page=引數控制。

(3)主函式:設定要爬取的最大頁數,並在迴圈中呼叫fetchAndParsePage方法。

(4)fetchAndParsePage:

  • 使用HttpClient傳送GET請求到指定的URL。
  • 檢查響應狀態碼是否為200(成功)。
  • 使用Jsoup解析HTML字串。
  • 選擇頁面上的文章標題元素(這裡假設標題在<h2 class="post-title">中,我們可能需要根據實際情況調整選擇器)。
  • 列印出每個找到的標題。

注意:

  • 請確保我們遵守目標網站的robots.txt規則和版權政策。
  • 本示例中的URL和選擇器是假設的,我們需要根據目標網站的實際結構進行調整。
  • 在實際應用中,我們可能還需要處理異常(如網路錯誤、HTML解析錯誤等)和進行效能最佳化(如設定合理的請求頭、連線超時時間等)。

2. 完整的程式碼示例

下面是一個完整的Java程式碼示例,它使用Apache HttpClient和Jsoup庫來從一個假設的部落格網站抓取文章標題。這個示例包括了必要的異常處理和一些基本的HTTP請求配置。

首先,確保我們已經將Apache HttpClient和Jsoup作為依賴項新增到我們的專案中。如果我們使用的是Maven,可以在pom.xml中新增以下依賴:

<dependencies>  
    <dependency>  
        <groupId>org.jsoup</groupId>  
        <artifactId>jsoup</artifactId>  
        <version>1.14.3</version>  
    </dependency>  
    <dependency>  
        <groupId>org.apache.httpcomponents</groupId>  
        <artifactId>httpclient</artifactId>  
        <version>4.5.13</version>  
    </dependency>  
</dependencies>

接下來是完整的Java程式碼示例:

import org.apache.http.client.methods.CloseableHttpResponse;  
import org.apache.http.client.methods.HttpGet;  
import org.apache.http.impl.client.CloseableHttpClient;  
import org.apache.http.impl.client.HttpClients;  
import org.apache.http.util.EntityUtils;  
import org.jsoup.Jsoup;  
import org.jsoup.nodes.Document;  
import org.jsoup.nodes.Element;  
import org.jsoup.select.Elements;  
  
public class BlogSpider {  
  
    private static final String BASE_URL = "http://example.com/blog?page=";  
  
    public static void main(String[] args) {  
        int maxPages = 5; // 假設我們只爬取前5頁  
  
        for (int i = 1; i <= maxPages; i++) {  
            String url = BASE_URL + i;  
            System.out.println("Fetching page: " + url);  
            try {  
                fetchAndParsePage(url);  
            } catch (Exception e) {  
                System.err.println("Error fetching and parsing page " + i + ": " + e.getMessage());  
            }  
        }  
    }  
  
    private static void fetchAndParsePage(String url) throws Exception {  
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {  
            HttpGet request = new HttpGet(url);  
            // 你可以在這裡設定請求頭,比如User-Agent  
            // request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");  
  
            try (CloseableHttpResponse response = httpClient.execute(request)) {  
                if (response.getStatusLine().getStatusCode() == 200) {  
                    String html = EntityUtils.toString(response.getEntity(), "UTF-8");  
                    Document doc = Jsoup.parse(html);  
  
                    // 假設每個文章標題都在<h2 class="post-title">標籤內  
                    Elements articleTitles = doc.select("h2.post-title");  
                    for (Element title : articleTitles) {  
                        System.out.println(title.text());  
                    }  
                } else {  
                    System.err.println("Failed to fetch page: HTTP status code " + response.getStatusLine().getStatusCode());  
                }  
            }  
        } catch (Exception e) {  
            throw e; // 或者你可以在這裡處理特定的異常,比如IOException  
        }  
    }  
}

在這個示例中,我新增了一個try-catch塊來捕獲fetchAndParsePage方法中可能丟擲的任何異常,並將其錯誤訊息列印到標準錯誤輸出。同時,我新增了一個註釋掉的請求頭設定示例,我們可以根據需要取消註釋並修改它。

請注意,這個示例中的BASE_URL和選擇器h2.post-title是假設的,我們需要根據我們要爬取的實際網站的HTML結構來修改它們。

此外,這個示例使用了try-with-resources語句來自動關閉CloseableHttpClientCloseableHttpResponse資源,這是一種更簡潔且安全的資源管理方式。

相關文章