在 Java 開發中,模擬 HTTP POST 請求進行網站登錄是常見需求。本文通過完整代碼示例,演示如何使用 HttpURLConnection 模擬登錄貓撲(Mop)論壇,並處理重定向、Cookie 管理及頁面內容解析。
HttpURLConnection 建立連接並發送 POST 數據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("登錄失敗,請檢查用戶名密碼或網站結構變化。");
}
}
}
貓撲登錄涉及多次重定向,關鍵在於禁用自動重定向(setInstanceFollowRedirects(false)),手動獲取 Location 頭部,然後向真實登錄接口發送 POST 請求。
登錄成功後,服務器會在響應頭中返回 Set-Cookie。需提取並拼接這些 Cookie,後續請求必須攜帶 Cookie 頭部才能維持會話。
使用 application/x-www-form-urlencoded 格式,注意對用戶名、密碼進行 URL 編碼(URLEncoder.encode),避免特殊字符導致錯誤。
登錄後獲取的 HTML 頁面通過 Jsoup 解析,根據特定 class(如 zhnc)提取用戶信息,判斷登錄是否成功。
本示例展示了 Java 原生網絡編程實現模擬登錄的完整流程:獲取重定向 → 發送憑證 → 管理 Cookie → 訪問受保護資源 → 解析驗證。雖然代碼量較大,但能深入理解 HTTP 協議細節,為爬蟲開發、自動化測試打下基礎。