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

Java 模擬 POST 請求實現貓撲論壇自動登錄完整示例

     編輯:Java 程式設計入門

前言

在 Java 開發中,模擬 HTTP POST 請求進行網站登錄是常見需求。本文通過完整代碼示例,演示如何使用 HttpURLConnection 模擬登錄貓撲(Mop)論壇,並處理重定向、Cookie 管理及頁面內容解析。

核心技術點

  • 使用 HttpURLConnection 建立連接並發送 POST 數據
  • 處理 302 重定向,獲取真實登錄地址
  • 手動管理 Cookie(Session ID 等)以維持會話狀態
  • 利用 Jsoup 解析登錄後的 HTML 頁面,驗證登錄結果

完整代碼實現

import java.io.*;
import java.net.*;
import java.util.Scanner;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class MopLoginSimulator {

    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.print("請輸入用戶名:");
        String username = scanner.next();
        System.out.print("請輸入密碼:");
        String password = scanner.next();
        
        // 執行登錄並保存響應頁面
        String outputPath = "d:/mop_login_result.html";
        loginAndSave(username, password, outputPath);
        
        // 解析頁面驗證登錄狀態
        parseResultPage(outputPath);
    }

    /**
     * 模擬登錄並保存響應頁面
     */
    public static void loginAndSave(String username, String password, String outPath) throws IOException {
        // 1. 訪問 passport 首頁獲取重定向地址
        URL url = new URL("https://passport.mop.com");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        setupCommonHeaders(connection);
        connection.setInstanceFollowRedirects(false); // 禁用自動重定向
        
        String redirectUrl = connection.getHeaderField("Location");
        if (redirectUrl == null) {
            throw new IOException("未獲取到重定向地址");
        }
        
        // 2. 向重定向地址發送登錄 POST 請求
        URL loginUrl = new URL(redirectUrl);
        HttpURLConnection loginConn = (HttpURLConnection) loginUrl.openConnection();
        setupCommonHeaders(loginConn);
        loginConn.setRequestProperty("Referer", redirectUrl);
        loginConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        loginConn.setDoOutput(true);
        loginConn.setDoInput(true);
        
        // 構建登錄表單數據
        String formData = "user_name=" + URLEncoder.encode(username, "UTF-8") 
                        + "&password=" + URLEncoder.encode(password, "UTF-8");
        
        try (OutputStreamWriter writer = new OutputStreamWriter(loginConn.getOutputStream(), "UTF-8")) {
            writer.write(formData);
            writer.flush();
        }
        
        // 3. 獲取並保存 Cookie
        StringBuilder cookieBuilder = new StringBuilder();
        for (int i = 1; ; i++) {
            String headerName = loginConn.getHeaderFieldKey(i);
            if (headerName == null) break;
            if ("Set-Cookie".equalsIgnoreCase(headerName)) {
                String cookie = loginConn.getHeaderField(i);
                String cookieValue = cookie.substring(0, cookie.indexOf(";"));
                cookieBuilder.append(cookieValue).append("; ");
            }
        }
        String cookies = cookieBuilder.toString();
        
        // 4. 攜帶 Cookie 訪問個人中心頁面
        URL personalUrl = new URL("https://passport.mop.com/personal");
        HttpURLConnection personalConn = (HttpURLConnection) personalUrl.openConnection();
        setupCommonHeaders(personalConn);
        personalConn.setRequestProperty("Referer", redirectUrl);
        personalConn.setRequestProperty("Cookie", cookies);
        personalConn.connect();
        
        // 5. 保存響應內容到文件
        try (InputStream in = personalConn.getInputStream();
             FileOutputStream fos = new FileOutputStream(outPath)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        }
        System.out.println("登錄響應已保存至:" + outPath);
    }

    /**
     * 設置通用請求頭
     */
    private static void setupCommonHeaders(HttpURLConnection conn) {
        conn.setRequestProperty("Connection", "keep-alive");
        conn.setRequestProperty("User-Agent", 
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
    }

    /**
     * 使用 Jsoup 解析頁面驗證登錄結果
     */
    private static void parseResultPage(String filePath) throws IOException {
        File input = new File(filePath);
        Document doc = Jsoup.parse(input, "UTF-8");
        
        // 根據頁面結構提取用戶信息區域
        Elements userInfo = doc.getElementsByClass("zhnc").select("ul li");
        if (!userInfo.isEmpty()) {
            System.out.println("登錄成功!用戶信息:" + userInfo.text());
        } else {
            System.out.println("登錄失敗,請檢查用戶名密碼或網站結構變化。");
        }
    }
}

關鍵步驟解析

1. 重定向處理

貓撲登錄涉及多次重定向,關鍵在於禁用自動重定向(setInstanceFollowRedirects(false)),手動獲取 Location 頭部,然後向真實登錄接口發送 POST 請求。

2. Cookie 管理

登錄成功後,服務器會在響應頭中返回 Set-Cookie。需提取並拼接這些 Cookie,後續請求必須攜帶 Cookie 頭部才能維持會話。

3. 表單數據編碼

使用 application/x-www-form-urlencoded 格式,注意對用戶名、密碼進行 URL 編碼(URLEncoder.encode),避免特殊字符導致錯誤。

4. Jsoup 解析驗證

登錄後獲取的 HTML 頁面通過 Jsoup 解析,根據特定 class(如 zhnc)提取用戶信息,判斷登錄是否成功。

注意事項

  • 網站結構可能變更,需根據實際頁面調整選擇器
  • 生產環境建議使用成熟的 HTTP 客戶端庫(如 HttpClient、OkHttp)
  • 涉及用戶憑證,請遵守網站服務條款,勿用於非法用途
  • 現代網站多採用 HTTPS,需處理 SSL 證書驗證

總結

本示例展示了 Java 原生網絡編程實現模擬登錄的完整流程:獲取重定向 → 發送憑證 → 管理 Cookie → 訪問受保護資源 → 解析驗證。雖然代碼量較大,但能深入理解 HTTP 協議細節,為爬蟲開發、自動化測試打下基礎。

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