¿Cómo extraer img src, title y alt de html usando php? [duplicar]

Resuelto Sam asked hace 54 años • 10 respuestas

Me gustaría crear una página donde todas las imágenes que se encuentran en mi sitio web estén enumeradas con título y representación alternativa.

Ya escribí un pequeño programa para buscar y cargar todos los archivos HTML, pero ahora no sé cómo extraerlos srcy de este HTML title:alt

<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />

Supongo que esto debería hacerse con alguna expresión regular, pero dado que el orden de las etiquetas puede variar y las necesito todas, realmente no sé cómo analizar esto de una manera elegante (podría hacerlo con el carácter duro manera char, pero eso es doloroso).

Sam avatar Jan 01 '70 08:01 Sam
Aceptado
$url="http://example.com";

$html = file_get_contents($url);

$doc = new DOMDocument();
@$doc->loadHTML($html);

$tags = $doc->getElementsByTagName('img');

foreach ($tags as $tag) {
       echo $tag->getAttribute('src');
}
karim avatar May 30 '2010 05:05 karim

EDITAR: ahora que lo sé mejor

Usar expresiones regulares para resolver este tipo de problemas es una mala idea y probablemente generará un código que no se puede mantener y no es confiable. Mejor utilice un analizador HTML .

Solución con expresión regular

En ese caso es mejor dividir el proceso en dos partes:

  • obtener todas las etiquetas img
  • extraer sus metadatos

Asumiré que su documento no es estricto con xHTML, por lo que no puede usar un analizador XML. EG con el código fuente de esta página web:

/* preg_match_all match the regexp in all the $html string and output everything as 
an array in $result. "i" option is used to make it case insensitive */

preg_match_all('/<img[^>]+>/i',$html, $result); 

print_r($result);
Array
(
    [0] => Array
        (
            [0] => <img src="/Content/Img/stackoverflow-logo-250.png" width="250" height="70" alt="logo link to homepage" />
            [1] => <img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />
            [2] => <img class="vote-down" src="/content/img/vote-arrow-down.png" alt="vote down" title="This was not helpful (click again to undo)" />
            [3] => <img src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG" height=32 width=32 alt="gravatar image" />
            [4] => <img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />

[...]
        )

)

Luego obtenemos todos los atributos de la etiqueta img con un bucle:

$img = array();
foreach( $result as $img_tag)
{
    preg_match_all('/(alt|title|src)=("[^"]*")/i',$img_tag, $img[$img_tag]);
}

print_r($img);

Array
(
    [<img src="/Content/Img/stackoverflow-logo-250.png" width="250" height="70" alt="logo link to homepage" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/Content/Img/stackoverflow-logo-250.png"
                    [1] => alt="logo link to homepage"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                )

            [2] => Array
                (
                    [0] => "/Content/Img/stackoverflow-logo-250.png"
                    [1] => "logo link to homepage"
                )

        )

    [<img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/content/img/vote-arrow-up.png"
                    [1] => alt="vote up"
                    [2] => title="This was helpful (click again to undo)"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                    [2] => title
                )

            [2] => Array
                (
                    [0] => "/content/img/vote-arrow-up.png"
                    [1] => "vote up"
                    [2] => "This was helpful (click again to undo)"
                )

        )

    [<img class="vote-down" src="/content/img/vote-arrow-down.png" alt="vote down" title="This was not helpful (click again to undo)" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/content/img/vote-arrow-down.png"
                    [1] => alt="vote down"
                    [2] => title="This was not helpful (click again to undo)"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                    [2] => title
                )

            [2] => Array
                (
                    [0] => "/content/img/vote-arrow-down.png"
                    [1] => "vote down"
                    [2] => "This was not helpful (click again to undo)"
                )

        )

    [<img src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG" height=32 width=32 alt="gravatar image" />] => Array
        (
            [0] => Array
                (
                    [0] => src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG"
                    [1] => alt="gravatar image"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                )

            [2] => Array
                (
                    [0] => "http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG"
                    [1] => "gravatar image"
                )

        )

   [..]
        )

)

Las expresiones regulares consumen mucha CPU, por lo que es posible que desees almacenar en caché esta página. Si no tiene un sistema de caché, puede modificar el suyo usando ob_start y cargando/guardando desde un archivo de texto.

¿Cómo funciona esto?

Primero, usamos preg_ match_ all , una función que obtiene cada cadena que coincide con el patrón y la muestra en su tercer parámetro.

Las expresiones regulares:

<img[^>]+>

Lo aplicamos en todas las páginas web html. Se puede leer como cada cadena que comienza con " <img", contiene caracteres que no son ">" y termina con > .

(alt|title|src)=("[^"]*")

Lo aplicamos sucesivamente en cada etiqueta img. Se puede leer como cualquier cadena que comience con "alt", "title" o "src", luego "=", luego ' " ', un montón de cosas que no son ' " ' y terminan con ' " ' .Aislar las subcadenas entre () .

Finalmente, cada vez que quieras lidiar con expresiones regulares, es útil tener buenas herramientas para probarlas rápidamente. Consulte este probador de expresiones regulares en línea .

EDITAR: respuesta al primer comentario.

Es cierto que no pensé en las (con suerte, pocas) personas que utilizan comillas simples.

Bueno, si usas solo ', simplemente reemplaza todos los " por '.

Si mezclas ambos. Primero deberías darte una bofetada :-), luego intenta usar ("|') en lugar de " y [^ø] para reemplazar [^"].

Bite code avatar Sep 27 '2008 11:09 Bite code

Sólo para dar un pequeño ejemplo del uso de la funcionalidad XML de PHP para la tarea:

$doc=new DOMDocument();
$doc->loadHTML("<html><body>Test<br><img src=\"myimage.jpg\" title=\"title\" alt=\"alt\"></body></html>");
$xml=simplexml_import_dom($doc); // just to make xpath more simple
$images=$xml->xpath('//img');
foreach ($images as $img) {
    echo $img['src'] . ' ' . $img['alt'] . ' ' . $img['title'];
}

Utilicé el DOMDocument::loadHTML()método porque este método puede manejar la sintaxis HTML y no obliga al documento de entrada a ser XHTML. Estrictamente hablando, la conversión a a SimpleXMLElementno es necesaria; simplemente simplifica el uso de xpath y los resultados de xpath.

Stefan Gehrig avatar Sep 26 '2008 10:09 Stefan Gehrig