Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Text einer Internetseite in Memo einlesen (https://www.delphipraxis.net/216910-text-einer-internetseite-memo-einlesen.html)

Rued 23. Mär 2025 14:09

AW: Text einer Internetseite in Memo einlesen
 
Sebastian, das ist für mich eine völlig fremde Welt. Wenn ich Deinen Code sehe, überlege ich, ob ich mir nicht ein neues Hobby suche, das Programmieren aufgebe.

Ganz herzlichen Dank für dieses Lehrstück! Das ist mein voller Ernst.

Darf ich trotzdem noch fragen, wie ich in Erfahrung bringe, welche Angaben "Data" noch so enthält? Zum Beispiel, ob das Spiel beendet ist, ob Halbzeit ist oder das Spiel verlegt wurde?
Habe ne Weile geschaut, ob ich da selbst hinterkomme, aber keine Chance in absehbarer Zeit.

jaenicke 23. Mär 2025 15:00

AW: Text einer Internetseite in Memo einlesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Rued (Beitrag 1547385)
Sebastian, das ist für mich eine völlig fremde Welt. Wenn ich Deinen Code sehe, überlege ich, ob ich mir nicht ein neues Hobby suche, das Programmieren aufgebe.

Das kann man alles lernen. Wichtig ist nur, dass du wirklich lernst und verstehst, was solcher Code eigentlich macht. Nicht auswendig lernen, sondern wirklich verstehen wie der Code funktioniert, denn genau das ist der entscheidende Unterschied. Wenn du soweit bist, kannst du das dann auch in anderen Situationen anwenden.

Das ist am Anfang nicht einfach, aber es lohnt sich, die Zeit zu investieren, auch wenn es schon funktioniert. Und du kannst natürlich jederzeit konkret fragen, wenn du etwas nicht verstehst. Für uns ist das Problem immer, dass wir nicht wissen, wo ein Verständnisproblem liegt.

Zitat:

Zitat von Rued (Beitrag 1547385)
Darf ich trotzdem noch fragen, wie ich in Erfahrung bringe, welche Angaben "Data" noch so enthält? Zum Beispiel, ob das Spiel beendet ist, ob Halbzeit ist oder das Spiel verlegt wurde?

Am besten drückst du im normalen Chrome Browser einfach mal F12, falls du das noch nicht gemacht hast. Dann drückst du Strg + Shift + C. Dann kannst du die einzelnen Elemente anklicken und siehst, wie die im Quelltext aussehen.
Vorsicht: Das sieht im Browser nicht 1:1 so aus wie du es bekommst.
Aber daran kannst du sehen, wonach du im Quelltext, den du dir ja einfach in eine Textdatei zur Ansicht speichern kannst, suchen musst.

Anhang 57451

In diesem Fall ist wichtig, dass Zeilenumbrüche im HTML-Quelltext <br /> (so bekommst du es) bzw. <br> (so siehst du es in Chrome) sind. Dementsprechend habe ich die Zeilen so trennen können. Und sie stecken in einem div-Container, der so aussieht: <div id="score-data">
Also kann ich danach suchen.

Viel musst du dafür über HTML nicht unbedingt wissen. Da sollte es reichen, wenn du dir den Quelltext ein wenig anschaust.

Rued 23. Mär 2025 15:24

AW: Text einer Internetseite in Memo einlesen
 
Zitat:

Zitat von jaenicke (Beitrag 1547386)
Das kann man alles lernen. Wichtig ist nur, dass du wirklich lernst und verstehst, was solcher Code eigentlich macht.
...

Hast Du da einen Tipp für Literatur oder Tutorials?
Zitat:

Zitat von jaenicke (Beitrag 1547386)
...
Am besten drückst du im normalen Chrome Browser einfach mal F12, falls du das noch nicht gemacht hast. Dann drückst du Strg + Shift + C.
...

Interessant, Strg + Shift + C kannte ich noch nicht.

HolgerX 23. Mär 2025 16:39

AW: Text einer Internetseite in Memo einlesen
 
Hmmm...

Zitat:

Zitat von jaenicke (Beitrag 1547381)
nichts mit dem Thema zu tun. Es geht um Android. ;-)

Stimmt..

Aber hat dann doch zum Ergebnis geführt ;)

Er hat u.a. nach einer Möglichkeit gesucht, das mit einem Browser in Delphi zu machen...
Mein Beispiel hat die Windows D6 Lösung gezeigt.

Dein Folgebeitrag dann die Lösung mit dem Aktuellen TWebBrowser unter Android..
Somit hat mein Beitrag einen kleinen Schubs gegeben ;)

Leider funktionieren diverse Seiten ohne Browser nicht, da deren Kontent erst im Browser per Java-Script zusammen gebaut wird und nicht im direkten HTML per Indy und Co zu bekommen ist.

Somit muss die Seite erst im Browser geladen werden, von diesem vollständig (teils mit Runterscrollen auf der Seite) gebaut werden, bevor alles da ist.


Wenn (habs erst gerade gesehen) wie hier bereits aller Kontent im HTML enthalten ist, dann sollte die Seite direkt herunter geladen und geparst werden.

Dies kann per RegExt oder mit einem vollwertigem HTML-Parser gemacht werden.

jaenicke 23. Mär 2025 16:58

AW: Text einer Internetseite in Memo einlesen
 
Zitat:

Zitat von Rued (Beitrag 1547387)
Hast Du da einen Tipp für Literatur oder Tutorials?

Keine spezielle für ein bestimmtes Thema in dem Zusammenhang. Lesenswert ist das Buch von Marco Cantú:
https://www.embarcadero.com/products...ascal-handbook

Zitat:

Zitat von Rued (Beitrag 1547387)
Interessant, Strg + Shift + C kannte ich noch nicht.

Ich benutze normalerweise den linken oberen Button, aber bevor ich beschreibe, welcher das ist... :-D

Zitat:

Zitat von HolgerX (Beitrag 1547389)
Mein Beispiel hat die Windows D6 Lösung gezeigt.

Die hatte er in der ursprünglichen Frage oben geschrieben und gefragt, wie das unter Android geht, weil es dort WebBrowser1.OleObject.... nicht gibt. :wink:

Rued 23. Mär 2025 18:03

AW: Text einer Internetseite in Memo einlesen
 
Zitat:

Zitat von HolgerX (Beitrag 1547389)
Hmmm...

Zitat:

Zitat von jaenicke (Beitrag 1547381)
nichts mit dem Thema zu tun. Es geht um Android. ;-)

Stimmt..

Aber hat dann doch zum Ergebnis geführt ;)

Er hat u.a. nach einer Möglichkeit gesucht, das mit einem Browser in Delphi zu machen...
Mein Beispiel hat die Windows D6 Lösung gezeigt.
...

Tut mir leid, den Anstoß brauchte es nicht. Den Thread habe ich wie folgt eingeleitet:
Zitat:

In meiner Android-App will ich eine Internetseite parsen, wie ich es in meinen PC-Anwendungen mache.

Leider funktioniert WebBrowser1.OleObject.document.body.innerText nicht.
Sehe gerade, dass auch Sebastian schon darauf hingewiesen hat.

Rued 23. Mär 2025 18:10

AW: Text einer Internetseite in Memo einlesen
 
Zitat:

Zitat von jaenicke (Beitrag 1547390)
Zitat:

Zitat von Rued (Beitrag 1547387)
Hast Du da einen Tipp für Literatur oder Tutorials?

Keine spezielle für ein bestimmtes Thema in dem Zusammenhang. Lesenswert ist das Buch von Marco Cantú:
https://www.embarcadero.com/products...ascal-handbook
...

Danke, habe ich mal heruntergeladen.

Rued 24. Mär 2025 16:31

AW: Text einer Internetseite in Memo einlesen
 
Was ich nicht verstehe ist, dass die Abfrage für die Seite https://m.flashscore.de/?d=0 funktioniert, nicht aber z.B. für https://m.flashscore.de/?d=-1 (gestrige Begegnungen) und über https://m.flashscore.de/?d=1 die morgigen Spiele nicht auswirft - obwohl die Seiten m. E. identisch aufgebaut sind.

Da hapert es jeweils schon daran, dass
Delphi-Quellcode:
HtmlContents := LoadHtml('https://m.flashscore.de/?d=-1');
nichts liefert.

Woran liegt das?

Ergänzung: Mir fällt gerade auf, dass auch die Abfrage von https://m.flashscore.de/?d=0 nur neun Begegnungen listet, also nur einen Bruchteil der Liste auf der Seite.

jaenicke 25. Mär 2025 02:48

AW: Text einer Internetseite in Memo einlesen
 
Es gibt einfach noch viel mehr Informationen, die enthalten sein können...
Deshalb wäre es ja, wie ich schon schrieb, sinnvoll, den Betreiber nach einer richtigen Schnittstelle zu fragen, statt die Seite auszulesen.

Ich habe das mal angepasst. Es macht aber wohl Sinn, dass du die Zeile selbst als String untersuchst (ParseGameLine), da du vermutlich so bald nicht die Regular Expression selbst anpassen kannst. Auch würde es helfen, wenn du einen Parser verwendest und so die Möglichkeiten behandeln kannst.

So funktioniert es jedenfalls erst einmal:
Delphi-Quellcode:
uses
  System.Generics.Collections, System.RegularExpressions, System.Net.HttpClientComponent, System.StrUtils;

type
  TGame = class
    Category: string;
    GameTime: string;
    Status: string;
    Opponent1, Opponent2: string;
    RedCards1, RedCards2: string;
    URL: string;
    MatchResult1, MatchResult2: string;
    MatchResultInfo: string;
  end;

function LoadHtml(const AUrl: string): string;
var
  NetHTTPClient: TNetHTTPClient;
begin
  NetHTTPClient := TNetHTTPClient.Create(nil);
  try
    Result := NetHTTPClient.get(AUrl).ContentAsString;
  finally
    NetHTTPClient.Free;
  end;
end;

function ParseGameLine(const AValue: string): TGame;
var
  RegEx: TRegEx;
  Match: TMatch;
begin
  RegEx := TRegEx.Create('<span(?: class="live")?>([0-9:+'']+)(?:<span[^>]*>(.*?)<\/span>)?<\/span>\s*([^<]+)(?:<img[^>]*class="rcard-(\d+)"[^>]*>)?\s*- ([^<]+)(?:<img[^>]*class="rcard-(\d+)"[^>]*>)?\s*<a href="([^"]+)" class="[^"]*">([0-9\-]+):([0-9\-]+)(.*?)<\/a>');
  Match := RegEx.Match(AValue);
  if Match.Success then
  begin
    Result := TGame.Create;
    Result.GameTime := Match.Groups[1].Value;
    if Match.Groups[2].Success then
      Result.Status := Match.Groups[2].Value;
    Result.Opponent1 := Match.Groups[3].Value;
    if Match.Groups[4].Success then
      Result.RedCards1 := Match.Groups[4].Value;
    Result.Opponent2 := Match.Groups[5].Value;
    if Match.Groups[6].Success then
      Result.RedCards2 := Match.Groups[6].Value;
    Result.URL := Match.Groups[7].Value;
    Result.MatchResult1 := Match.Groups[8].Value;
    Result.MatchResult2 := Match.Groups[9].Value;
    if Match.Groups[10].Success then
      Result.MatchResultInfo := Match.Groups[10].Value;
  end
  else
    Result := nil;
end;

procedure FindGames(const ATarget: TObjectList<TGame>);
const
  cContentsContainer = '<div id="score-data">';
  cHeaderStart = '<h4>';
  cHeaderEnd = '</h4>';
var
  HtmlContents, CurrentCategory, CurrentLine: string;
  Data: TArray<string>;
  CurrentGame: TGame;
  i: Integer;
begin
  HtmlContents := LoadHtml('https://m.flashscore.de/?d=-1');
  HtmlContents := HtmlContents.Substring(HtmlContents.IndexOf(cContentsContainer) + Length(cContentsContainer));
  Data := HtmlContents.Split(['<br />']);
  for i := 0 to High(Data) do
  begin
    CurrentLine := Data[i];
    if CurrentLine.StartsWith(cHeaderStart) then
    begin
      CurrentCategory := CurrentLine.Substring(Length(cHeaderStart), CurrentLine.IndexOf(cHeaderEnd));
      if CurrentCategory.IndexOf('<') > 0 then
        CurrentCategory := CurrentCategory.Substring(0, CurrentCategory.IndexOf('<')).Trim;
      CurrentLine := CurrentLine.Substring(CurrentLine.IndexOf(cHeaderEnd) + Length(cHeaderEnd));
    end;
    CurrentGame := ParseGameLine(CurrentLine);
    if Assigned(CurrentGame) then
    begin
      CurrentGame.Category := CurrentCategory;
      ATarget.Add(CurrentGame);
    end;
  end;
end;

procedure TForm288.Button1Click(Sender: TObject);
var
  CurrentGame: TGame;
  Games: TObjectList<TGame>;
  i: Integer;
begin
  Games := TObjectList<TGame>.Create(True);
  try
    FindGames(Games);
    for i := 0 to Games.Count - 1 do
    begin
      CurrentGame := Games[i];
      Memo1.Lines.Add(CurrentGame.Category + sLineBreak
        + 'Spielzeit: ' + CurrentGame.GameTime + ' ' + CurrentGame.Status + sLineBreak
        + 'Gegner: ' + CurrentGame.Opponent1 + IfThen(CurrentGame.RedCards1 <> '', ' (' + CurrentGame.RedCards1 + ' rote Karte(n))', '')
          + ' gegen ' + CurrentGame.Opponent2 + IfThen(CurrentGame.RedCards2 <> '', ' (' + CurrentGame.RedCards2 + ' rote Karte(n))', '') + sLineBreak
        + 'URL: ' + CurrentGame.URL + sLineBreak
        + 'Ergebnis: ' + CurrentGame.MatchResult1 + ' : ' + CurrentGame.MatchResult2 + ' ' + CurrentGame.MatchResultInfo + sLineBreak + sLineBreak);
    end;
  finally
    Games.Free;
  end;
end;

Rued 25. Mär 2025 14:09

AW: Text einer Internetseite in Memo einlesen
 
Danke Dir Sebastian für die Anpassung. Das Ergebnis ermuntert, sich selbst mit der Thematik zu befassen, irritiert mich aber auch, da die Funktion, die HtmlContents liefert und zuvor ein unvollständiges Ergebnis lieferte, unverändert blieb, jetzt aber alle Zeilen erfasst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz