[java] [angularjs] rechtstreeks API aanroepen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Beste tweakerts,

Naar aanleiding van mijn vorige topic: [java] & [angularjs] add token header aan een form ben ik nu aan het uitvogelen hoe ik vanuit Java een website moet scrapen die vanuit AngularJS is opgebouwd. Het plan is om de achterliggende API rechtstreeks aan te roepen. Nu heb ik in de desbetreffende pagina (als het goed is) de javascript verwijzing gevonden die de inlog procedure afhandelt. Als deze doorlopen is kom je in een soort overzichtsscherm waarna mijn reguliere web-scraping links weer werken.

Ik heb echter geen idee hoe ik deze API aanroep vanuit Java, heeft iemand wat hints? Er zijn niet veel Java Angular scraping sites te vinden. Als uitgangspositie heb ik de login/pass informatie als ook een token die mee moet worden gegeven.

Hier is de angular Javascript code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(function() {
    "use strict";
    angular.module("signInApp", ["loadingDataButton"]).config(["$httpProvider", function(n) {
        n.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"
    }])
})(),
function() {
    "use strict";

    function n(n) {
        function t(t) {
            return n.defaults.headers.common.__RequestVerificationToken = angular.element('input[name="__RequestVerificationToken"]').attr("value"), n.post("/sign-in", t)
        }
        return {
            signIn: t
        }
    }
    angular.module("signInApp").factory("signInService", n);
    n.$inject = ["$http"]
}(),
function() {
    function n(n) {
        function r(n) {
            return decodeURIComponent((new RegExp("[?|&]" + n + "=([^&;]+?)(&|#|;|$)").exec(location.search) || [null, ""])[1].replace(/\+/g, "%20")) || null
        }

        function u(n) {
            t.submitDisabled = n.$invalid
        }

        function f() {
            t.submitDisabled = !0;
            t.isLoading = !0;
            t.incorrectError = "";
            n.signIn({
                model: {
                    password: t.password,
                    user: t.user,
                    rememberMe: !1
                },
                returnUrl: i
            }).then(function(n) {
                n.data.returnUrl ? window.location.href = n.data.returnUrl : (t.responseModel = n.data, t.submitDisabled = n.data.lockedOut, t.isLoading = !1)
            }, function() {
                t.isLoading = !1;
                t.submitDisabled = !1;
                t.responseModel.errorMessage = "An unexpected error has occurred while processing your request. Please try again."
            })
        }
        var t = this,
            i = r("ReturnUrl");
        t.$onInit = function() {
            t.incorrectError = "";
            t.isLoading = !1;
            t.user = "";
            t.password = "";
            t.submitDisabled = !0;
            t.loading = !1;
            t.onType = u;
            t.signIn = f
        }
    }
    angular.module("signInApp").component("signIn", {
        templateUrl: "/Areas/Main/Apps/SignIn/sign-in.component.html",
        controller: n
    });
    n.$inject = ["signInService"]
}()5


Zou ik dit kunnen met de standaard HtmlUnit Java libraries die ik nu ook gebruik?

Beste antwoord (via Red devil op 10-07-2017 20:34)


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Simpel voorbeeldje met OkHttp en Jackson:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.okhttp.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

public class OkHttp {
    private OkHttpClient client;
    private ObjectMapper mapper;

    @Before
    public void setup() {
        client = new OkHttpClient();
        mapper = new ObjectMapper();
    }

    @Test
    public void getRequest() throws IOException {
        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts")
                .get()
                .build();

        Response response = client.newCall(request).execute();

        System.out.println(response.body().string());
    }

    @Test
    public void postRequest() throws IOException {
        RequestDto requestDto = new RequestDto("Some text");

        RequestBody body = RequestBody.create(MediaType.parse("application/json"), mapper.writeValueAsString(requestDto));

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts")
                .header("X-My-Header", "HeaderValue")
                .post(body)
                .build();

        Response response = client.newCall(request).execute();

        System.out.println(response.body().string());
    }

    public static class RequestDto {
        private final String content;

        public RequestDto(final String content) {
            this.content = content;
        }

        public String getContent() {
            return content;
        }
    }
}


Laat maar weten als je vragen hebt hierover.

https://niels.nu

Alle reacties


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Allright, leerzaam dagje. Ik heb zojuist via de Chrome developer tools een breakpoint op elke XHR request. Vervolgens kwam er een relevante request naar boven drijven. Daar zit de login/pass en token in:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Request URL:https://www.website.com/sign-in
Referrer Policy:no-referrer-when-downgrade
Request Headers
Provisional headers are shown
__RequestVerificationToken:4hBj6_cG2xaDlOBieSh1PdeYzkHqUXrDqsWm5W76QQZRNvCiOEPlp4CNEl2UiGnkFL44_A0nj2qa4FWcPBbxYuwzla8pkUCfsuhqJl7JaNluQN9coTwBj7_1meqBMw0KXy5wEoH675ZA9dtHfcNGJQ2
Accept:application/json, text/plain, */*
Content-Type:application/json;charset=UTF-8
Origin:https://www.website.com
Referer:https://www.website.com/sign-in
User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payload
view source
{model: {password: "password", user: "user", rememberMe: false}, returnUrl: null}
model
:
{password: "password", user: "user", rememberMe: false}
user
:
"user"
password
:
"password"
rememberMe
:
false
returnUrl
:
null


Moet nu dus Request Payload nog in zien te stellen. De headers gaan volgens mij via setAdditionalHeader. Volgens mij betreft het een request van het type XMLHttpRequest. Als iemand nog gaten ziet hoor ik het graag :-)

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Je kunt ook met de network tab alleen XHR requests tonen he, dan zie je ze meteen langskomen.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Hydra schreef op maandag 3 juli 2017 @ 09:31:
Je kunt ook met de network tab alleen XHR requests tonen he, dan zie je ze meteen langskomen.
Klopt, alleen zag ik de meest relevante XHR request maar heel kort, was zo weg. Maar toen kwam ik erachter dat je breakpoints kunt zetten en voila, daar was de betreffende XHR request waar alles in zat (password/user en token in de header). Nu probeer ik deze XmlHttpRequest mbt Java HtmlUnit om te zetten maar ben gewend dat ik wel wat voorbeelden online vind... nu bijna niks te vinden voor java.

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Red devil schreef op maandag 3 juli 2017 @ 10:58:
Klopt, alleen zag ik de meest relevante XHR request maar heel kort, was zo weg.
Nee? Die blijven gewoon staan? Je doet vermoedelijk iets verkeerd.
Maar toen kwam ik erachter dat je breakpoints kunt zetten en voila, daar was de betreffende XHR request waar alles in zat (password/user en token in de header). Nu probeer ik deze XmlHttpRequest mbt Java HtmlUnit om te zetten maar ben gewend dat ik wel wat voorbeelden online vind... nu bijna niks te vinden voor java.
Komt omdat een REST api aanspreken van HtmlUnit gewoon een enorm rare keuze is. Gebruik gewoon een 'standaard' HTTP client (Apache Http Client of OkHttp).

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Hydra schreef op maandag 3 juli 2017 @ 11:02:
[...]


Nee? Die blijven gewoon staan? Je doet vermoedelijk iets verkeerd.
Ongetwijfeld dat het aan mij ligt maar ik kon hem niet meer terug vinden...... :'(
Komt omdat een REST api aanspreken van HtmlUnit gewoon een enorm rare keuze is. Gebruik gewoon een 'standaard' HTTP client (Apache Http Client of OkHttp).
Thanks! Ik ga eens Apache Http client of OkHttp checken.

Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Simpel voorbeeldje met OkHttp en Jackson:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.okhttp.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

public class OkHttp {
    private OkHttpClient client;
    private ObjectMapper mapper;

    @Before
    public void setup() {
        client = new OkHttpClient();
        mapper = new ObjectMapper();
    }

    @Test
    public void getRequest() throws IOException {
        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts")
                .get()
                .build();

        Response response = client.newCall(request).execute();

        System.out.println(response.body().string());
    }

    @Test
    public void postRequest() throws IOException {
        RequestDto requestDto = new RequestDto("Some text");

        RequestBody body = RequestBody.create(MediaType.parse("application/json"), mapper.writeValueAsString(requestDto));

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts")
                .header("X-My-Header", "HeaderValue")
                .post(body)
                .build();

        Response response = client.newCall(request).execute();

        System.out.println(response.body().string());
    }

    public static class RequestDto {
        private final String content;

        public RequestDto(final String content) {
            this.content = content;
        }

        public String getContent() {
            return content;
        }
    }
}


Laat maar weten als je vragen hebt hierover.

https://niels.nu


Acties:
  • +1 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Hydra schreef op maandag 3 juli 2017 @ 11:23:
Simpel voorbeeldje met OkHttp en Jackson:

Java:
1
snippet


Laat maar weten als je vragen hebt hierover.
Super bedankt, ga vanavond even testen en laat nog wel weten _/-\o_

Acties:
  • +1 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 29-09 15:25
Red devil schreef op maandag 3 juli 2017 @ 11:11:
[...]

Ongetwijfeld dat het aan mij ligt maar ik kon hem niet meer terug vinden...... :'(
Tabje Network -> Preserve log aanzetten :)

Full-stack webdeveloper in Groningen


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 13:55
Hydra schreef op maandag 3 juli 2017 @ 11:23:
Simpel voorbeeldje met OkHttp en Jackson:
<knip>
Dankzij uitstekende tips van Hydra (ook via PMs) werd ik weer op weg geholpen. _/-\o_
Hij zag dat er naast de __RequestVerificationToken in de form tevens een gelinkte cookie betrokken was bij een eventuele succesvolle post. Na wat zoekwerk kwam ik erachter dat je met een CookieJar cookies kunt afvangen en in een nieuwe get/post request kunt injecteren. Heb nog wel de code van internet enigszins veranderd omdat in de oorspronkelijke code bij elke redirect (en in mijn geval waren er dat nogal een paar) de collectie cookies werden overgeschreven. Ik verzamel ze nu en dat lijkt te werken:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
CookieJar cookieJar = new CookieJar() {
                public HashMap<String, List<Cookie>> cookieStore = new HashMap<>();

                @Override
                public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {

                    List<Cookie> before = loadForRequest(url);

                    if (before != null) {
                        List<Cookie> combined = new LinkedList<>();
                        combined.addAll(before);
                        combined.addAll(cookies);
                        cookieStore.put(url.host(), combined);
                                                                       
                    } else {
                        cookieStore.put(url.host(), cookies);
                                               
                    }
                }

                @Override
                public List<Cookie> loadForRequest(HttpUrl url) {
                    List<Cookie> cookies = cookieStore.get(url.host());
                    return cookies != null ? cookies : new ArrayList<Cookie>();
                }
            };

            client = new OkHttpClient.Builder()
                    .cookieJar(cookieJar)
                    .addNetworkInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Chain chain) throws IOException {
                            System.out.println("url: " + chain.request().url());
                            return chain.proceed(chain.request());
                        }
                    })
                    .build();


Nogmaals bedankt Hydra :)

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Graag gedaan!

https://niels.nu

Pagina: 1