Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Obtener Datos de Pagina web Usando Chromiun para delphi (https://www.clubdelphi.com/foros/showthread.php?t=96219)

Dergon 04-05-2023 16:23:33

Obtener Datos de Pagina web Usando Chromiun para delphi
 
Hola Amigos, estoy con un problemita que no consigo resolver de ninguna manera, estoy usando un componente para delphi 10.3 CEF4Delphi, este componente facilita usar paginas modernas en Chromium, estoy intentando pasar un valor de una pagina a una variable string, ya conseguí mostrarlo en una ventana emergente del navegador, pero mi inconveniente ahora es obtener el valor de esa ventana emergente,
también e echo que en el input y el botón de búsqueda haga un click automáticamente, solo el inconveniente es obtener el valor de la ventana emergente.
Aqui e codigo utilizado.
Código Delphi [-]
var JScode:string;
begin
JSCode := 'var table = document.getElementsByTagName("table")[0];' +
  'var rows = table.getElementsByTagName("tr");' +
  'for (var i = 0; i < rows.length; i++) {' +
  ' var cells = rows[i].getElementsByTagName("td");' +
  ' for (var j = 0; j < cells.length; j++) {' +
  '   alert(cells[j].innerHTML);' +
  ' }' +
  '}' ;
Chromium1.Browser.MainFrame.ExecuteJavaScript(JSCode, 'about:blank', 0);



en esta imagen muestra en la ventana emergente la informacion que necesito copiarlo a una variable.

dec 05-05-2023 17:39:56

Hola a todos,

Si no me equivoco, estás usando el componente Chromium de CEF4Delphi. Si esto es así, este componente no tiene ningún evento "OnWebMessageReceived", tal como tiene el componente "TEdgeBrowser". La idea de dicho evento es que tú pudieras ejecutar desde Delphi un código JavaScript similar al siguiente:

Código Delphi [-]
JSCode := 'var table = document.getElementsByTagName("table")[0];' +
  'var rows = table.getElementsByTagName("tr");' +
  'for (var i = 0; i < rows.length; i++) {' +
  ' var cells = rows[i].getElementsByTagName("td");' +
  ' for (var j = 0; j < cells.length; j++) {' +
  '   window.chrome.webview.postMessage({ID: "my-message", CONTENT: cells[j].innerHTML});' +
  ' }' +
  '}' ;

EdgeBrowser1.ExecuteScript(JSCode);

Como ves, se trata de obtener el valor que quieras desde el HTML DOM, en este caso "cells[j].innerHTML", y, enviarlo dentro de un objeto JSON que pasas como argumento a "window.chrome.webview.postMessage". Hay que decir que es posible que tuvieras algún problema con ese valor en particular, puesto que, al tratarse de HTML, no podrías "ponerlo" sin más dentro del JSON.

Pero, la idea es esa: tú ejecutas "window.chrome.webview.postMessage", y, al hacerlo, se disparará el evento "OnWebMessageReceived" del componente "TEdgeBrowser", que, podría codificarse de la siguiente forma:

Código Delphi [-]
procedure TForm1.EdgeBrowser1WebMessageReceived(Sender: TCustomEdgeBrowser;
  Args: TWebMessageReceivedEventArgs);
var
  Msg: PWideChar;
  MessageId, MessageContent: string;
  InputJson, Data: TJSONValue;
begin
  Msg := ''; // Very important to initialize this variable!

  Args.ArgsInterface.Get_webMessageAsJson(Msg);
  InputJson := TJSONObject.ParseJSONValue(Msg);

  MessageId := InputJson.GetValue<string>('ID');

  if MessageId = 'my-message' then
  begin
    MessageContent := InputJson.GetValue<string>('CONTENT');
    ShowMessage(MessageContent);
  end;
end;

Como ves, el evento recibiría el objeto JSON, nosotros podríamos entonces acceder a su propiedad "ID", y, actuaríamos en consecuencia dependiendo de dicho "ID", en este caso, simplemente, mostrando luego en un "ShowMessage" la propiedad "CONTENT" del objeto JSON, donde tú pusieras el valor que te interesase enviar a Delphi desde JavaScript al ejecutar "window.chrome.webview.postMessage".

Como ves, de esta forma se facilitan bastante las cosas, sin embargo, el componente Chromium de CEF4Delphi, no dispone de un evento "OnWebMessageReceived", al menos en la versión que yo tengo instalada. Si te fijas en el ejemplo "DOMVisitor" que se incluye con dicho componente, verás que se utiliza cierto "truco" que de alguna manera es similar, aunque, no igual.

Lo que se hace en dicho ejemplo "DOMVisitor" es enviar a la consola de Chromium un determinado mensaje, y, como el componente Chromium de CEF4Delphi sí que dispone de un evento "OnConsoleMessage", tú podrías estar al tanto de lo que llega a la consola: que sería el mensaje que tú mismo habrías enviado previamente. Puedes echar un vistazo al ejemplo "DOMVisitor" y estudiarlo en ese sentido: este ejemplo va un poco más allá, puesto que, utiliza el evento "OnConsoleMessage" para enviar un mensaje al componente, que, a su vez se recibe en el evento "OnProcessMessageReceived", que, no debemos confundir con el que incorpora "TEdgeBrowser", y, que, acaso puedas "saltarte", utilizando sin más el evento "OnConsoleMessage".

La idea sería ejecutar un código similar al siguiente:

Código Delphi [-]
JSCode := 'var table = document.getElementsByTagName("table")[0];' +
  'var rows = table.getElementsByTagName("tr");' +
  'for (var i = 0; i < rows.length; i++) {' +
  ' var cells = rows[i].getElementsByTagName("td");' +
  ' for (var j = 0; j < cells.length; j++) {' +
  '   console.log({ID: "my-message", CONTENT: cells[j].innerHTML});' +
  ' }' +
  '}' ;

EdgeBrowser1.ExecuteScript(JSCode);

No he podido probarlo, pero, es posible que el siguiente código en el evento "OnConsoleMessage" funcionase más o menos como se espera:

Código Delphi [-]
procedure TForm1.Chromium1ConsoleMessage(Sender: TObject;
  const browser: ICefBrowser; level: Cardinal; const message, source: ustring;
  line: Integer; out Result: Boolean);
var
  MessageId, MessageContent: string;
  InputJson, Data: TJSONValue;
begin
  InputJson := TJSONObject.ParseJSONValue(message);

  MessageId := InputJson.GetValue<string>('ID');

  if MessageId = 'my-message' then
  begin
    MessageContent := InputJson.GetValue<string>('CONTENT');
    ShowMessage(MessageContent);
  end;
end;
end;

Ojo porque lo que quisiera es que cogieses la idea general de lo que tienes que hacer. Como digo, no he podido probarlo, y, estoy seguro de que algunas cosas habrá que limarlas: por ejemplo, hemos dicho que no podrías poner HTML dentro del JSON, pero, podrías codificar el HTML en Base64, por ejemplo. Tampoco sería acaso necesario usar JSON, aunque, de alguna manera tienes que poder identificar el mensaje cuando lo recibas, entonces, podrías usar JSON, o acaso añadir al principio de lo que quieres enviar alguna cadena que te permita identificar de qué mensaje se trata.

Otra cosa a considerar es que el código que he puesto arriba en el evento "OnConsoleMessage", posiblemente fallaría. ¿Por qué? Pues porque en realidad estamos usando "el truco de enviarnos un mensaje cuando mandemos algo a la consola", pero, la consola, por norma general, va a recibir muchas más cosas que nuestros mensajes, de modo que, como digo, es necesario identificar que aquello que nos llegue en ese evento sea "lo que nosotros esperamos". Por lo demás, seguramente, la siguiente línea debería ser puesta en un bloque "try ... except":

Código Delphi [-]
InputJson := TJSONObject.ParseJSONValue(message);

... eso en el caso de que nos decidamos a usar JSON: como digo, en ese evento, es posible que recibamos muchos mensajes que no son "los nuestros", por decirlo así, y, es probable que ese "ParseJSONValue" fallase causando alguna excepción si se intenta parsear "algo" que no es una cadena que contenga un objeto JSON. En fin, espero que hayas cogido la idea. También podrías acaso preguntar en el GitHub de Chromium de CEF4Delphi (añadiendo alguna "issue") si existe un evento similar al que hemos visto que existe en "TEdgeBrowser", no sé si acaso podrías incluso plantearte usar "TEdgeBrowser", en fin, espero que todo esto te sirva de alguna ayuda.

Si tienes alguna duda, no la tengas en escribir aquí y trataremos de echarte una mano en lo posible.

Dergon 08-05-2023 20:42:36

(resolvido)
 
Muchas gracias dec, la información que me has pasado me fue de mucha ayuda, lo realize de la siguiente manera, pasandolo a console.log y recibiendo en el evento Chromium1ConsoleMessage ..Muchas gracias.


La franja horaria es GMT +2. Ahora son las 00:45:54.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi