httpclient模擬需要登陸之後才能訪問第三方網站(並且需要一些人工參與的操作)

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()");
    }
}

打印日誌:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章