[Gelöst] Navigation auf einer Webseite durch Sourcecode

Alle Fragen zur Netzwerkkommunikation
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

vielen Dank für dein kleines Demoprogram habe mich durchgearbeitet und auch schon einiges herausgefunden/ umgestellt.

Doch anscheinend habe ich noch nicht ganz verstanden wie man die Übergabewerte korrekt übergibt.

Was schon geht:
- Einloggen (dank dir)
- Navigation zur Log Seite (z.B. https://www.geocaching.com/play/geocache/gc3m3wh/log)

Gemäß deines Beispiels beim Einloggen habe ich nun versucht den "Absenden" Button zu drücken.

Code: Alles auswählen

 
    Request := TStringList.Create;
    Request.Add(
   // Hier jeweils die Namen der Objekte
      'LogDate=' + EncodeURLElement('2017-09-18') + '&'
      + 'LogText=' + EncodeURLElement('Testlog, wird wieder gelöscht.') + '&'
      + 'LogTypeId=' + EncodeURLElement('4') + '&' // Todo : 4 entspricht "Write note", wenn ich das richtig verstanden habe
      );
    CopyStringsToStream(Request, fClient.Document);
    fClient.MimeType := 'application/x-www-form-urlencoded';
    fClient.Headers.Clear;
    fClient.HTTPMethod('POST', 'https://www.geocaching.com/play/geocache/gc3m3wh/log/submitLog'); // Hinter die URL wird die ID des Buttons gehängt
    rc := fClient.ResultCode;
 
   (*
    * Hier bekomme ich einen ResultCode 404
         * Die Debug ausgabe ist leer
    *)

    CopyStreamToStrings(fClient.Document, form1.SynEdit1.Lines); // -- Debug
    Request.free;
 


Und hier der meines Erachtens relevante Teil aus dem HTML-Source der Log Seite:

Code: Alles auswählen

 
            <section class="region log-type-wrapper">
                <div class="loading">
                    Lädt...
                </div>
                <h2 class="log-heading h6">Diesen Geocache loggen</h2>
                <div class="log-types">
                    <select class="log-type" name="LogTypeId">
                            <option value="4">Anmerkung hinterlassen</option>
                            <option value="3">Nicht gefunden</option>
                    </select>
                </div>
            </section>
            <section id="coordinateInput"></section>
            <section class="region log-content-wrapper upload-panel">
                <div id="logContent">
                    <div class="flatpickr-wrapper">
                        <label class="visually-hidden" for="LogDate">Select a date</label>
                        <input class="log-date" data-alt-input="true" data-val="true" data-val-date="The&#32;field&#32;LogDate&#32;must&#32;be&#32;a&#32;date." data-val-required="Bitte&#32;wähle&#32;ein&#32;Logdatum." id="LogDate" name="LogDate" type="date" value="2017-09-18" />
                        <svg class="icon" height="16" width="16">
                            <use xlink:href="/play/Content/ui-icons/sprites/global.svg#icon-caret-down-currentcolor"></use>
                        </svg>
                    </div>
                    <div id="reportProblemInfo" class="banner-problem"></div>
 
                    <label class="visually-hidden" for="LogText">Hinterlasse einen Kommentar</label>
                    <textarea class="decorated&#32;log-text" cols="20" data-val="true" data-val-maxlength="Kommentare&#32;können&#32;nicht&#32;länger&#32;als&#32;LogText&#32;Zeichen&#32;sein." data-val-maxlength-max="4000" data-val-required="Bitte&#32;hinterlasse&#32;einen&#32;Kommentar." id="LogText" name="LogText" rows="4">
</textarea>
                    <div class="upload-preview"></div>
                    <div class="file-error field-validation-error"></div>
                    <span class="character-counter"></span>
                    <div class="error-summary"></div>
                    <div id="logAttachments" class="btn-group">
                    </div>
                </div>
            </section>
            <section class="region trackables-wrapper" id="trackablesPanel"></section>
            <section class="region">
                <div id="submitLog" class="submit-wrapper">
                    <button type="submit" class="btn btn-primary btn-submit">
                        Absenden
                    </button>
                    <div class="validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div>
                </div>
            </section>
 
--
Just try it

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von m.fuchs »

corpsman hat geschrieben:

Code: Alles auswählen

fClient.HTTPMethod('POST', 'https://www.geocaching.com/play/geocache/gc3m3wh/log/submitLog'); // Hinter die URL wird die ID des Buttons gehängt

Wie kommst du darauf, dass die Button-ID drangehängt werden muss? Das dürfte schon der Fehler sein.

Und aufgepasst: auch dieses Form besitzt einen __RequestVerificationToken, den musst du auch wieder mitgeben.
Und aufgepasst zwei: auf der Seite befinden sich mehrere __RequestVerificationToken, jedes Form hat einen eigenen. Du musst den richtigen mitsenden, dabei hilft der aktuelle Code zum Extrahieren von mir nicht.

Vielleicht komme ich heute oder morgen noch mal dazu da weiterzuschreiben.

corpsman hat geschrieben:Solltest du um den 11.11. wieder in Stuttgart sein, da gibts wieder ein Stuttgarter Lazarus Treffen...

Jo, bin dabei.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

Jo, bin dabei.

Cool, habe schon wieder ein paar nette Samples gebastelt, Thema DBase und Shape Dateien und 3D-Visualisierung von GPS Daten..

Das andere Probiere ich morgen gleich mal aus, vielen Dank für deine Geduld.

Die anderen Übergaben hatte ich richtig verstanden ?

Wenn das klappt fehlt nur noch das Verwalten der TB's und schon kann ich loggen *g*.
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

Jupi, Erfolg,

habe es nun geschafft meinen ersten Log zu machen, vielen Dank.

Eine Frage hab ich noch, wie geht das mit den TBs ? wenn ich den Quelltext der Homepage ansehe steht da nichts von meinen TBs

da steht nur :

Code: Alles auswählen

            <section class="region trackables-wrapper" id="trackablesPanel"></section>


Im Browser rollt sich das TB Menü nach unten aus, wenn man da drauf klickt, aber auch dann ändert sich der Queltext der Seite nicht. Ich geh nun mal davon aus, dass man das irgendwie nachladen kann, aber wie ?
--
Just try it

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von m.fuchs »

Hab mir das mal mit dem Netzwerkdebugger von Chrome angesehen, was bei den TB passiert.

Dafür machst du einen gesondert POST auf https://www.geocaching.com/api/proxy/tr ... activities und sendest eine JSON-Objekt mit:

Code: Alles auswählen

[{"logType":{"id":"75"},"date":"2017-09-19","geocache":{"gcCode":"GC1NG9M"},"referenceCode":"TB288HP"}]

Die id ist entweder 75 für Visit oder 14 für Drop. Die anderen Parameter sollten klar sein.

Ist jetzt nicht ausprobiert, nur aus dem Datenverkehr gelesen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

Sodale, hab noch ein wenig rum recharchiert und folgenden Code zusammen gebastelt :

Code: Alles auswählen

 
.. 
      logdate := '2017-09-20';
      setlength(FList, 1);
      flist[0].Cache := 'GC3M3WH';
      setlength(flist[0].TBs, 1);
      FList[0].TBs[0] := 'TB8E1X0';
 
      Request := TStringList.Create;
      request.add('[');
      For j := 0 To high(Logs[i].TBs) Do Begin
        suff := '';
        If (high(Logs[i].TBs) <> 0) And (j <> high(Logs[i].TBs)) Then Begin
          Suff := ',';
        End;
        Request.Add(
          //Die id ist entweder 75 für Visit oder 14 für Drop -- Wir loggen immer als Visit !!
          '{"logType":{"id":"75"},"date":"' + logdate + '","geocache":{"gcCode":"' + Logs[i].Cache + '"},"referenceCode":"' + Logs[i].TBs[j] + '"}' + Suff
          );
      End;
      request.add(']');
      CopyStringsToStream(Request, fClient.Document);
      fClient.MimeType := 'application/json';// hat sich geändert, sind ja nun keine URL encodierten daten mehr
      fClient.Headers.Clear;
      fClient.HTTPMethod('POST', 'https://www.geocaching.com/api/proxy/trackable/activities');
      rc := fClient.ResultCode;
      CopyStreamToStrings(fClient.Document, form1.SynEdit1.Lines); // -- Debugg
      Request.free;     
 


Leider kriege ich nun den Resultcode 401, was wohl bedeutet, das ich nicht authentifiziert bin :(.

Direkt danach kommt folgender Code :

Code: Alles auswählen

 
    (*
     * Der Eigentliche Log
     *)

    fClient.Headers.Clear;
    // Laden der Logseite, damit wir das Request Token bekommen
    fClient.HTTPMethod('GET', 'https://www.geocaching.com/play/geocache/' + lowercase(Logs[i].Cache) + '/log');
    rc := fClient.ResultCode;
    Follow_Links;
    __RequestVerificationToken := Get__RequestVerificationToken();
    Request := TStringList.Create;
    Request.Add(
      '__RequestVerificationToken=' + __RequestVerificationToken + '&'
      + 'LogText=' + EncodeURLElement(Logs[i].Comment) + '&' // Todo: auf 4000 zeichen Beschränken
      + 'LogDate=' + EncodeURLElement(logdate) + '&' // Todo: Auslesen aus dem Log
      + 'LogTypeId=' + LogStateToOption(Logs[i].State) + '&' // Todo : Ist hart auf "4" codiert
      );
    CopyStringsToStream(Request, fClient.Document);
    fClient.MimeType := 'application/x-www-form-urlencoded';
    fClient.Headers.Clear;
    fClient.HTTPMethod('POST', 'https://www.geocaching.com/play/geocache/' + lowercase(Logs[i].Cache) + '/log');
    rc := fClient.ResultCode;
    CopyStreamToStrings(fClient.Document, form1.SynEdit1.Lines); // -- Debugg
    Request.free
 


Der funktioniert..
--
Just try it

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von m.fuchs »

corpsman hat geschrieben:Leider kriege ich nun den Resultcode 401, was wohl bedeutet, das ich nicht authentifiziert bin :(.


Das habe ich befürchtet. Dieser Weg die Trackables zu loggen geht über die API von Groundspeak und wird wohl im Normalfall von irgendwelchen Javascripts bedient.
Vermutlich müssen dafür noch spezielle Authtication-Header übertragen werden. Mal schauen ob ich da was sehe.

Letztendlich gibt sich Groundspeak viel Mühe damit man ihr System nicht von außen ansteuern kann. Wäre ja auch kein Problem, wenn sie weiterhin neue Projekte für ihre API zulassen würden. Wenigstens für Premium-User sollte das drin sein.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

Eine weitere Idee zum Thema TB's (Leider blicke ich nicht wie man diese HTML Debugg Dinger im Browser installiert, bzw kann ich Google Chrome nicht installieren weil mein OS 32-Bit ist)

Wenn ich den Gemachten Log wieder Editiere sieht der Source anders aus :

Code: Alles auswählen

 
 <h4>Trackables abgelegt? <a href="javascript&#058;void(0);" id="aHelpDroppedOff"><img src="/images/icons/16/help.png" /></a></h4>   
 
        <table id="tblTravelBugs" class="LogTrackablesTable Table">
            <thead>
                <tr>
                    <th style="width:100px;">Trackingnummer</th>
                    <th>Name</th>
                    <th style="width:125px;">Aktion</th>
                </tr>
            </thead>
            <tbody>
 
                <tr id="ctl00_ContentBody_LogBookPanel1_uxTrackables_repTravelBugs_ctl01_row">
            <td><a href="/track/details.aspx?tracker=Z9F1TM">Z9F1TM</a></td>
            <td>Corpsman</td>
            <td>
                        <select name="ctl00$ContentBody$LogBookPanel1$uxTrackables$repTravelBugs$ctl01$ddlAction" id="ctl00_ContentBody_LogBookPanel1_uxTrackables_repTravelBugs_ctl01_ddlAction" class="trackable-action-dropdown">
               <option value="7395951">&#8211; Keine Aktion &#8211;</option>
               <option value="7395951_DroppedOff">Abgelegt</option>
               <option value="7395951_Visited">Besucht</option>
 
            </select>
                    </td>
         </tr>
 


Könnte man da nicht irgend einen Post Request basteln, welchen ich dann an ?? schicke und dort mache ich dann

Code: Alles auswählen

 
ctl00_ContentBody_LogBookPanel1_uxTrackables_repTravelBugs_ctl01_ddlAction=7395951_Visited
 


Nur das Validationstoken habe ich noch nicht gefunden, und die URL wo ich das hin schicke .. da steht keine URL

Code: Alles auswählen

 <p>
            <input type="submit" name="ctl00$ContentBody$LogBookPanel1$btnSubmitLog" value="Logeintrag&#32;übermitteln" onclick="javascript&#058;WebForm_DoPostBackWithOptions(new&#32;WebForm_PostBackOptions(&quot;ctl00$ContentBody$LogBookPanel1$btnSubmitLog&quot;,&#32;&quot;&quot;,&#32;true,&#32;&quot;&quot;,&#32;&quot;&quot;,&#32;false,&#32;false))" id="ctl00_ContentBody_LogBookPanel1_btnSubmitLog" class="Button" />
        </p>
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

Sodale,

es ist wieder ein wenig Zeit vergangen und ich habe neue Erkenntnisse erlangt.

nach sehr viel ausprobieren habe ich mittels Firefox einen Mitschnitt des HTML Traffics hinbekommen (leider nicht den Kompletten) aber immerhin ein wenig. Indem 26000 Zeilen Log den mir Firefox generiert hat habe ich rum gesucht und einen interessanten Teil gefunden inmitten all dieser Anfragen hohlt sich der Browser ein API Autentifikationstoken (durch senden eines Get an eine bestimmte URL)
Das Ergebnis sieht dann so aus :

Code: Alles auswählen

 
    {"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6IkNvcnBzbWFuIiwic3ViIjoiN2ZjNzk0NmMtMWRhZC00ZDFiLWI3MTEtMzI0ZjYwMmRjMWVjIiwiYWlkIjoiMTQzMDg1MTkiLCJsZ2QiOiIzNmE3MDY0OS1kOWU5LTQzNzktOWY2MS1jYzAwZTkyMDVlOTQiLCJpc3MiOiJodHRwczovL29hdXRoLmdlb2NhY2hpbmcuY29tL3Rva2VuIiwiYXVkIjoiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy91c2VyZGF0YTogMTdiMWJhYjQtNmM1My00NTRjLThlYTktMmE2NjQ4OTFhNDMxIiwiZXhwIjoxNTA3MTAyMjM5LCJuYmYiOjE1MDcwOTg2Mzl9.GJzLHCLarcZMM_BWqXxATxf_47FL3Ma-w2-lEZLkEsU","token_type":"bearer","expires_in":"3599"}
 
 


Diesen JSON Code einfach an meine Anfrage mit an zu fügen

Code: Alles auswählen

 Request := TStringList.Create;
      request.Add(APIToken + ','); // -- In API Token steht die Antwort von der Get anfrage
      request.add('[');
      For j := 0 To high(Logs[i].TBs) Do Begin
        suff := '';
        If (high(Logs[i].TBs) <> 0) And (j <> high(Logs[i].TBs)) Then Begin
          Suff := ',';
        End;
        Request.Add(
          //Die id ist entweder 75 für Visit oder 14 für Drop -- Wir loggen immer als Visit !!
          '{"logType":{"id":"75"},"date":"' + logdate + '","geocache":{"gcCode":"' + Logs[i].Cache + '"},"referenceCode":"' + Logs[i].TBs[j] + '"}' + Suff
          );
      End;
      request.add(']');
      CopyStringsToStream(Request, fClient.Document);
      fClient.MimeType := 'application/json';
      fClient.Headers.Clear;
      fClient.HTTPMethod('POST', 'https://www.geocaching.com/api/proxy/trackable/activities');
      rc := fClient.ResultCode;     


Reicht aber nicht, bzw gehe ich davon aus, dass ich das falsch mache. Evtl muss ich das als Cokie mit angeben oder wieder in die URL mit eincodieren, doch wie ?

Laut Wikipedia

Die Anfrage kann nicht ohne gültige Authentifizierung durchgeführt werden. Wie die Authentifizierung durchgeführt werden soll, wird im „WWW-Authenticate“-Header-Feld der Antwort übermittelt.

gibt es also ein Header Feld wo ich das machen soll, kennt das jemand ?
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: [Gelöst] Navigation auf einer Webseite durch Sourcecode

Beitrag von corpsman »

So für alle Mitleser, habe das Thema nun auf Gelöst gesetzt. und Präsentiere hier nun Geschwindt die Finale Lösung

UNter Windwos32-Bit sowie Linux 64-Bit funktioniert es nun. Komischerweise bekomme ich beim Loggen der Travelbugs auf meinem Odroid U3 eine 404 Antwort (wo es doch der Gleiche Code ist ...

Die Lösung bestand übrigens darin das Token im Autorisierungs Header mit zu senden. Unten das Codesnippet welches nun alles Loggt. Danke allen Mitdiskutierern und natürlich besonders m.Fuchs.

Code: Alles auswählen

   (*
     * Loggen der TB's
     *)

    If assigned(Logs[i].TBs) Then Begin
      RefreshAPIToken; // Hohlen eines API-Tokens, falls notwendig
      // basteln des JSON-RAW Textes uzm loggen der TB's
      Request := TStringList.Create;
      request.add('[');
      For j := 0 To high(Logs[i].TBs) Do Begin
        suff := '';
        If (high(Logs[i].TBs) <> 0) And (j <> high(Logs[i].TBs)) Then Begin
          Suff := ',';
        End;
        Request.Add(
          //Die id ist entweder 75 für Visit oder 14 für Drop -- Wir loggen immer als Visit !!
          '{"logType":{"id":"75"},"date":"' + logdate + '","geocache":{"gcCode":"' + Logs[i].Cache + '"},"referenceCode":"' + Logs[i].TBs[j] + '"}' + Suff
          );
      End;
      request.add(']');
      CopyStringsToStream(Request, fClient.Document);
      fClient.MimeType := 'application/json';
      fClient.Headers.Clear;
      // Beim Zugriff auf API Seiten muss zusätzlich das API-Token mit angegeben werden !
      fClient.Headers.Add('Authorization: ' + fAPIToken.token_type + ' ' + FAPIToken.access_token);
      fClient.HTTPMethod('POST', 'https://www.geocaching.com/api/proxy/trackable/activities');
      If fClient.ResultCode <> 200 Then Begin
        fLastError := fLastError + LineEnding + 'Could not log travel bugs, for "' + Logs[i].Cache + '" [HTMLResult=' + inttostr(fClient.ResultCode) + ']';
        exit;
      End;
      Request.free;
    End;
--
Just try it

Antworten