Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Parsear HTML (https://www.clubdelphi.com/foros/showthread.php?t=92944)

lago 23-03-2018 19:26:44

Parsear HTML
 
Hola, llevo un buen rato buscando la mejor manera de parsear contenido de un fichero HTML.

Lo que necesito es extraer las rutas de las imágenes <img src="http://SITIO/IMAGEN.JPG"> de un fichero HTML que descargo.

En PHP o Perl creo recordar que era bastante sencillo con las expresiones regulares pero en C.... me muero... Se os ocurre algo?

Gracias y un saludo!

Casimiro Notevi 23-03-2018 21:02:29

¿Extraer http://SITIO/IMAGEN.JPG ?

lago 23-03-2018 21:07:40

Hola Casimiro, exacto, de un HTML que guardo en un memo por ejemplo.

Código PHP:

<html>
<
head><title> </head></title>
<
body>

<
p>
Lalalala
<img src="http://www.loquesea.com/imagen1.jpg">
<
img src="http://www.loquesea.com/imagen2.jpg">
<
img src="http://www.loquesea.com/imagen3.jpg">
</
p>

</
body>

</
html

De ahi necesito recoger:
http://www.loquesea.com/imagen1.jpg
http://www.loquesea.com/imagen2.jpg
http://www.loquesea.com/imagen3.jpg

escafandra 23-03-2018 22:01:16

Código PHP:

AnsiString ExtractURLImages(AnsiString Text)
{
  
AnsiString Result;
  
CHAR *Text.c_str();

  
CHARstrstr(T".jpg");
  while(
R){
     
R[4] = 0;
     
strrchr(T'\"');
     if(
TResult += T+1;
     
Result += "\n";
     
R+5;
     
strstr(T".jpg");
  }
  return 
Result;


Ejemplo de uso:

Código PHP:

Memo->Text ExtractURLImages(HTML_Text); 


Saludos.

lago 24-03-2018 11:19:07

Muchas gracias Escafandra, en página más complejas falla pero me da por donde arrancar!

escafandra 24-03-2018 14:07:29

Cita:

Empezado por lago (Mensaje 525252)
Muchas gracias Escafandra, en página más complejas falla pero me da por donde arrancar!

El código asume que las URLs buscadas están entre paréntesis, y se refieren a imágenes jpg.
Puede añadirse la búsqueda de otros formatos de imagen y que el comienzo de la cadena buscada sea por "http://www."

Saludos.

mamcx 24-03-2018 19:52:58

Cita:

Empezado por lago (Mensaje 525252)
Muchas gracias Escafandra, en página más complejas falla pero me da por donde arrancar!

HTML no es para parsear con regex ni manualmente:

https://stackoverflow.com/questions/...lanation-in-la

a menos que tengas MUY especificado que es lo que quieres.

---

Si de todas maneras es solo detectar las URLS necesitas hacer un regex mas complejo o el parseo manual es mucho mas trabajado.

Ñuño Martínez 26-03-2018 12:57:54

Como te han dicho, analizar código HTML es complejo, y más si quieres cumplir con la norma de forma estricta y manejar correctamente código HTML mal construido. Es más, para hacerlo bien tendrás que construir un parser completo.

De todas formas, puedes simplificar un poco la cosa. Te lo pongo en pseudo-código:
Código:

  BUCLE
    SI se encuentra "<img " en HTML
      Desde esa posición, buscar 'src="', si no se encuentra ERROR
      Extraer el texto desde esa posición hasta las siguientes comillas
      quitar de HTML todo lo que preceda al texto extraido
    SINO
      Salir del BUCLE
    FIN SI
  REPETIR

Sigue sin manejar bien código mal formado (por ejemplo, si se encuentra un <img /> sin "src") pero en los casos bien construidos debería funcionar.

ecfisa 26-03-2018 23:02:35

Hola.
Cita:

Empezado por lago (Mensaje 525240)
...
Lo que necesito es extraer las rutas de las imágenes <img src="http://SITIO/IMAGEN.JPG"> de un fichero HTML que descargo.
...

Otra opción para extraer las rutas bajo la condición que las cadenas comiencen en "<img src=" y terminen en "jpg">:
Código PHP:

void getUrls(TStrings *sourceTStrings *target)
{
  const 
charINI "<img src=\"";
  const 
charFIN "jpg\">";

  
target->Clear();
  
TStrings *ori = new TStringList;
  try
  {
    
ori->Text source->Text;
    for ( 
int i 0ori->Counti++ )
    {
      
AnsiString aux ori->Strings[i];
      
int p aux.Pos(INI);
      if ( 
)
      {
        
+= strlen(INI) - 1;
        
aux aux.SubString(p+1aux.Length());
        
aux aux.SubString(1aux.Pos(FIN) + 2);
        
target->Add(aux);
      }
    }
  }
  
__finally
  
{
    
delete(ori);
  }


Ej. uso:
Código PHP:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  
getUrls(Memo1->LinesMemo2->Lines); 


Resultado de la prueba:


Saludos :)

lago 27-03-2018 12:21:01

Si que es cierto lo que decís, es peliagudo parsear una codificación que aún teniendo un standar es flexible como para que cada uno lo haga como le da la gana. En este caso me metí en este jardín por que solo tengo que parsear la salida html de dos páginas muy concretas.

Ecfisa muchas gracias por tu código, junto con el de escafandra me han venido genial!

Muchas gracias a todos por vuestras respuestas

Un saludo!!

Jorge.


La franja horaria es GMT +2. Ahora son las 07:29:10.

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