本範例展示如何使用 Apache HttpClient 4.x 模擬瀏覽器登入京東商城(舊版介面)。核心難點在於登入表單包含動態生成的隱藏欄位(uuid、驗證碼相關參數),需先 GET 登入頁面解析 HTML 取得這些值,再組裝 POST 請求完成認證。
public class JD {
// 目標 URL
private static final String REDIRECT_URL = "https://order.jd.com/center/list.action";
private static final String LOGIN_PAGE_URL = "https://passport.jd.com/uc/login";
private static final String LOGIN_SUBMIT_URL = "https://passport.jd.com/uc/loginService";
private DefaultHttpClient httpclient = new DefaultHttpClient();
private HttpResponse response;
...
}
getParams() 方法 GET 登入頁,使用字串分割(簡易 HTML 解析)提取 uuid 與另一組動態鍵值對:
public Map<String, String> getParams() {
Map<String, String> map = new HashMap<>();
String html = getText(LOGIN_PAGE_URL);
// 提取 uuid
String uuid = html.split("name=\"uuid\" value=\"")[1].split("\"/>")[0];
map.put("uuid", uuid);
// 提取另一隱藏欄位
String[] parts = html.split("<span class=\"clr\"></span><input type=\"hidden\" name=\"");
String[] kv = parts[1].split("/>")[0].trim().split("\"");
map.put(kv[0], kv[2]); // key=kv[0], value=kv[2]
return map;
}
注意:生產環境強烈建議使用 Jsoup 或 HTMLParser 進行健壯的 HTML 解析,字串分割極易因頁面結構微調而失效。
login() 方法建構 HttpPost,包含固定欄位(帳號、密碼、跳轉頁)與動態解析的參數:
private boolean login() {
Map<String, String> params = getParams();
HttpPost httpost = new HttpPost(LOGIN_SUBMIT_URL);
List<BasicNameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("ReturnUrl", REDIRECT_URL));
nvps.add(new BasicNameValuePair("loginname", Constant.userName));
nvps.add(new BasicNameValuePair("nloginpwd", Constant.password));
nvps.add(new BasicNameValuePair("loginpwd", Constant.password));
// 加入動態參數
params.forEach((k, v) -> nvps.add(new BasicNameValuePair(k, v)));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
try {
response = httpclient.execute(httpost);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
httpost.abort();
}
}
登入成功後,伺服器回傳 302 重定向,需從 Location 標頭獲取目標 URL 並再次 GET:
private String getRedirectLocation() {
BufferedHeader header = (BufferedHeader) response.getFirstHeader("Location");
return header != null ? header.getValue() : null;
}
public void printText() {
if (login()) {
System.out.println(getText(REDIRECT_URL));
String loc = getRedirectLocation();
if (loc != null) System.out.println(getText(loc));
}
}
Jsoup.connect(url).get() 配合 CSS 選擇器 input[name=uuid] 提取。HttpClientBuilder、ClassicHttpRequest)或改用 OkHttp/Java 11 HttpClient。BasicCookieStore 持久化 Session,避免重複登入。本程式碼僅供技術學習與測試,嚴禁用於大規模爬取、暴力破解、帳號盜用等違法行為。請遵守《計算機信息網路國際聯網管理暫行規定》及目標網站 robots.txt 與服務條款。
範例完整演示了「GET 頁面 → 解析動態參數 → POST 表單 → 處理重定向」的經典模擬登入流程。雖具體目標站點已更新,但核心邏輯對理解 HTTP 協議、表單認證、HtmlClient 使用仍具參考價值。