httpclient模擬用戶登陸並訪問目標頁面....作個個人記錄!
最近接了個功能,調用第三方的API獲取數據,入庫到我們自己平臺!但是提供方網站上的東西比較簡陋:
簡單說明下:
1.獲取數據的接口需要唯一標識access_token;
2.access_token的獲取需要通過code去獲取;
3.code的獲取需要引導用戶(第三方平臺的登陸用戶)打開一個授權頁面進行授權之後,重定向地址上 而假如沒有登陸還需要你先進行登陸;
難點就在這個需要引導用戶打開授權頁面進行授權
1). 這裏面我們直接獲取數據,用戶就是我們自己在該第三方平臺的賬號;
2). 沒有登陸直接去訪問會跳轉到登陸頁面;
3). 登陸了之後,會有個授權頁面,需要手動去點擊授權按鈕才真正跳轉;
如下列圖:
然後查看上述頁面的源代碼,可找到發送請求的URL以及參數:
登陸的地址和參數:
點擊授權連接按鈕所作的操作:
上代碼(HttpClients模擬 + Jsoup解析html)
-----此例是比較簡單的沒有驗證碼的登錄頁面
package com.fulihui.daweixinke.test.conn;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
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;
import org.junit.Test;
import org.near.toolkit.security.codec.MD5Coder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;
/**
* <pre>
* 模擬需要登陸之後才能訪問第三方網站
* 並且需要一些人工參與的操作
* </pre>
*
* @author wang_wx
* @Date 2017-08-24
*/
public class EasyLoginNextPageA {
private String userName = "我是用戶名";
private String password = "我是密碼";
@Test
public void loginNext() throws IOException {
BasicCookieStore cookieStore = new BasicCookieStore();
// 全局用這一個httpClient對象模擬真實的一個瀏覽器中操作
CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
try {
// 模擬用戶登錄
HttpPost httpLogin = new HttpPost("xxxxxxxxxxxxxx/index.php/auth/auth/login");// 指向一個沒有驗證碼的登錄頁面
List<NameValuePair> nvps = new ArrayList<>();
nvps.add(new BasicNameValuePair("username", userName));// 用戶名對應的key
nvps.add(new BasicNameValuePair("password", MD5Coder.md5Encode(password)));// 密碼對應的key
httpLogin.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse respLogin = httpClient.execute(httpLogin);
try {
HttpEntity entity = respLogin.getEntity();
out.println("respLogin------------>>" + respLogin.toString());
out.println("Login form get: " + respLogin.getStatusLine());
EntityUtils.consume(entity);
out.println("Initial set of cookies:");
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
out.println("Cookie-" + i + "==" + cookies.get(i).toString());
}
}
} finally {
respLogin.close();
}
// 利用會話保持,繼續訪問目標地址
HttpGet httpGetAuth = new HttpGet("xxxxxxxxxxxxxxx/index.php/Auth/Auth/auth?app_id=xxxxxx&redirect_uri=回調地址&response_type=code");
CloseableHttpResponse respAuth = httpClient.execute(httpGetAuth);
String entityAuthStr = "";
try {
out.println(respAuth.getStatusLine());
HttpEntity entityAuth = respAuth.getEntity();
entityAuthStr = EntityUtils.toString(entityAuth);
out.println("get Auth cookies:");
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
out.println("- " + cookies.get(i).toString());
}
}
out.println("訪問目標地址的結果--------------------->>" + entityAuthStr);//把結果打印出來看一下
EntityUtils.consume(entityAuth);
} finally {
respAuth.close();
}
// 解析登陸之後訪問目標地址的html頁面 獲取目標form表單元素
Document doc = Jsoup.parseBodyFragment(entityAuthStr);
String title = doc.title();
out.println("title-------->>" + title);
Element element = doc.body();
Elements form = element.select("[name='authForm']");// 授權的form表單
out.println(form);
String actionUrl = form.attr("action");
String app_id = element.select("[name='app_id']").val();
String redirect_uri = element.select("[name='redirect_uri']").val();
String state = element.select("[name='state']").val();
String key = element.select("[name='key']").val();
String format = element.select("[name='format']").val();
// 利用會話保持,繼續模擬點擊授權按鈕 提交form表單
HttpPost httpPostGetCode = new HttpPost(actionUrl);
List<NameValuePair> nvps2 = new ArrayList<>();
nvps2.add(new BasicNameValuePair("app_id", app_id));
nvps2.add(new BasicNameValuePair("redirect_uri", redirect_uri));
nvps2.add(new BasicNameValuePair("state", state));
nvps2.add(new BasicNameValuePair("key", key));
nvps2.add(new BasicNameValuePair("format", format));
httpPostGetCode.setEntity(new UrlEncodedFormEntity(nvps2));
CloseableHttpResponse respGetCode = httpClient.execute(httpPostGetCode);
try {
HttpEntity entityGetCode = respGetCode.getEntity();
out.println("respAuth------------>>" + respGetCode.toString());
// 最終目的 獲取Location中的url中的某一值
Header location = respGetCode.getFirstHeader("Location");
out.println("location------------>>" + location.getValue());
EntityUtils.consume(entityGetCode);
} finally {
respGetCode.close();
}
} finally {
httpClient.close();
}
}
@Test
public void test111() {
String password = "我是密碼";
String encode = MD5Coder.md5Encode(password);
out.println("encode的值是:---" + encode + ",當前方法=EasyLoginNextPageA.test111()");
}
}
打印日誌: