usar - ¿Cómo extraer img src, title y alt de html usando php?
usar atributo alt en html (21)
EDITAR: ahora que sé mejor
Usar la expresión regular para resolver este tipo de problema es una mala idea y es probable que conduzca a un código inmanejable y poco confiable. Mejor usar un analizador HTML .
Solución con regexp
En ese caso, es mejor dividir el proceso en dos partes:
- obtener toda la etiqueta img
- extraer sus metadatos
Asumiré que su documento no es estricto en xHTML, por lo que no puede usar un analizador XML. EG con este código fuente de la 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 requieren una gran cantidad de CPU, por lo que es posible que desee almacenar en caché esta página. Si no tiene un sistema de caché, puede modificar el suyo utilizando 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 lo coloca 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
", no contiene caracteres ">" y termina con un> .
(alt|title|src)=("[^"]*")
Lo aplicamos sucesivamente en cada etiqueta img. Puede leerse como cada cadena que comience por "alt", "title" o "src", luego como "=", luego como "" '', un montón de cosas que no son'' "''y termina con'' '''' '' . Aislar las subcadenas entre () .
Finalmente, cada vez que desee tratar con expresiones regulares, es útil tener buenas herramientas para probarlas rápidamente. Verifique este probador de expresiones regulares en línea .
EDIT: respuesta al primer comentario.
Es cierto que no pensé en las (con suerte pocas) personas que usan comillas simples.
Bueno, si solo usas '', simplemente reemplaza todo el'' por ''.
Si mezclas ambos Primero debe abofetearlo a usted mismo :-), luego intente usar ("| '') en su lugar o" y [^ ø] para reemplazar [^ "].
Me gustaría crear una página donde todas las imágenes que residen en mi sitio web se enumeran con título y representación alternativa.
Ya me escribí un pequeño programa para buscar y cargar todos los archivos HTML, pero ahora estoy atascado en cómo extraer src
, title
y alt
de este HTML:
<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />
Supongo que esto debería hacerse con algunas expresiones regulares, pero dado que el orden de las etiquetas puede variar, y las necesito todas, realmente no sé cómo analizarlas de una manera elegante (podría hacerlo con el carácter duro por char, pero eso es doloroso).
¿Qué le parece usar una expresión regular para encontrar las etiquetas img (algo así como "<img[^>]*>"
), y luego, para cada etiqueta img, puede usar otra expresión regular para buscar cada atributo.
Tal vez algo así como " ([a-zA-Z]+)=/"([^"]*)/""
para encontrar los atributos, aunque es posible que desee permitir que las comillas no estén allí si se trata de una etiqueta sopa ... Si fuera así, podría obtener el nombre del parámetro y el valor de los grupos dentro de cada coincidencia.
Aquí está LA solución, en PHP:
Simplemente descargue QueryPath y luego haga lo siguiente:
$doc= qp($myHtmlDoc);
foreach($doc->xpath(''//img'') as $img) {
$src= $img->attr(''src'');
$title= $img->attr(''title'');
$alt= $img->attr(''alt'');
}
Eso es todo, ¡listo!
Aquí hay una función de PHP Cojeé juntos de toda la información anterior para un propósito similar, es decir, ajustar el ancho y las propiedades de la etiqueta de la imagen sobre la marcha ... un poco torpe, tal vez, pero parece funcionar de manera confiable:
function ReSizeImagesInHTML($HTMLContent,$MaximumWidth,$MaximumHeight) {
// find image tags
preg_match_all(''/<img[^>]+>/i'',$HTMLContent, $rawimagearray,PREG_SET_ORDER);
// put image tags in a simpler array
$imagearray = array();
for ($i = 0; $i < count($rawimagearray); $i++) {
array_push($imagearray, $rawimagearray[$i][0]);
}
// put image attributes in another array
$imageinfo = array();
foreach($imagearray as $img_tag) {
preg_match_all(''/(src|width|height)=("[^"]*")/i'',$img_tag, $imageinfo[$img_tag]);
}
// combine everything into one array
$AllImageInfo = array();
foreach($imagearray as $img_tag) {
$ImageSource = str_replace(''"'', '''', $imageinfo[$img_tag][2][0]);
$OrignialWidth = str_replace(''"'', '''', $imageinfo[$img_tag][2][1]);
$OrignialHeight = str_replace(''"'', '''', $imageinfo[$img_tag][2][2]);
$NewWidth = $OrignialWidth;
$NewHeight = $OrignialHeight;
$AdjustDimensions = "F";
if($OrignialWidth > $MaximumWidth) {
$diff = $OrignialWidth-$MaximumHeight;
$percnt_reduced = (($diff/$OrignialWidth)*100);
$NewHeight = floor($OrignialHeight-(($percnt_reduced*$OrignialHeight)/100));
$NewWidth = floor($OrignialWidth-$diff);
$AdjustDimensions = "T";
}
if($OrignialHeight > $MaximumHeight) {
$diff = $OrignialHeight-$MaximumWidth;
$percnt_reduced = (($diff/$OrignialHeight)*100);
$NewWidth = floor($OrignialWidth-(($percnt_reduced*$OrignialWidth)/100));
$NewHeight= floor($OrignialHeight-$diff);
$AdjustDimensions = "T";
}
$thisImageInfo = array(''OriginalImageTag'' => $img_tag , ''ImageSource'' => $ImageSource , ''OrignialWidth'' => $OrignialWidth , ''OrignialHeight'' => $OrignialHeight , ''NewWidth'' => $NewWidth , ''NewHeight'' => $NewHeight, ''AdjustDimensions'' => $AdjustDimensions);
array_push($AllImageInfo, $thisImageInfo);
}
// build array of before and after tags
$ImageBeforeAndAfter = array();
for ($i = 0; $i < count($AllImageInfo); $i++) {
if($AllImageInfo[$i][''AdjustDimensions''] == "T") {
$NewImageTag = str_ireplace(''width="'' . $AllImageInfo[$i][''OrignialWidth''] . ''"'', ''width="'' . $AllImageInfo[$i][''NewWidth''] . ''"'', $AllImageInfo[$i][''OriginalImageTag'']);
$NewImageTag = str_ireplace(''height="'' . $AllImageInfo[$i][''OrignialHeight''] . ''"'', ''height="'' . $AllImageInfo[$i][''NewHeight''] . ''"'', $NewImageTag);
$thisImageBeforeAndAfter = array(''OriginalImageTag'' => $AllImageInfo[$i][''OriginalImageTag''] , ''NewImageTag'' => $NewImageTag);
array_push($ImageBeforeAndAfter, $thisImageBeforeAndAfter);
}
}
// execute search and replace
for ($i = 0; $i < count($ImageBeforeAndAfter); $i++) {
$HTMLContent = str_ireplace($ImageBeforeAndAfter[$i][''OriginalImageTag''],$ImageBeforeAndAfter[$i][''NewImageTag''], $HTMLContent);
}
return $HTMLContent;
}
El script debe editarse así
foreach( $result[0] as $img_tag)
porque preg_match_all devuelve una matriz de matrices
Existe mi solución para recuperar solo imágenes del contenido de cualquier publicación en contenido wordpress o html. `
$content = get_the_content();
$count = substr_count($content, ''<img'');
$start = 0;
for ($i=0;$i<$count;$i++) {
if ($i == 0){
$imgBeg = strpos($content, ''<img'', $start);
$post = substr($content, $imgBeg);
} else {
$imgBeg = strpos($post, ''<img'', $start);
$post = substr($post, $imgBeg-2);
}
$imgEnd = strpos($post, ''>'');
$postOutput = substr($post, 0, $imgEnd+1);
$postOutput = preg_replace(''/width="([0-9]*)" height="([0-9]*)"/'', '''',$postOutput);
$image[$i] = $postOutput;
$start= $imgEnd + 1;
}
print_r($image);
`
Puede escribir una expresión regular para obtener todas las etiquetas img ( <img[^>]*>
), y luego utilizar simple explotar: $res = explode("/"", $tags)
, el resultado será algo como esto:
$res[0] = "<img src=";
$res[1] = "/image/fluffybunny.jpg";
$res[2] = "title=";
$res[3] = "Harvey the bunny";
$res[4] = "alt=";
$res[5] = "a cute little fluffy bunny";
$res[6] = "/>";
Si elimina la etiqueta <img
antes de la explosión, obtendrá una matriz en forma de
property=
value
por lo que el orden de las propiedades es irrelevante, solo utiliza lo que le gustará.
Puedes usar simplehtmldom . La mayoría de los selectores jQuery son compatibles en simplehtmldom. Un ejemplo se da a continuación
// Create DOM from URL or file
$html = file_get_html(''http://www.google.com/'');
// Find all images
foreach($html->find(''img'') as $element)
echo $element->src . ''<br>'';
// Find all links
foreach($html->find(''a'') as $element)
echo $element->href . ''<br>'';
RE esta solución:
$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'');
}
¿Cómo se obtiene la etiqueta y el atributo de múltiples archivos / URL?
Hacer esto no funcionó para mí:
foreach (glob("path/to/files/*.html") as $html) {
$doc = new DOMDocument();
$doc->loadHTML($html);
$tags = $doc->getElementsByTagName(''img'');
foreach ($tags as $tag) {
echo $tag->getAttribute(''src'');
}
}
Si desea usar regEx, ¿por qué no es tan fácil como esto?
preg_match_all(''% (.*)=/"(.*)/"%Uis'', $code, $matches, PREG_SET_ORDER);
Esto devolverá algo así como:
array(2) {
[0]=>
array(3) {
[0]=>
string(10) " src="abc""
[1]=>
string(3) "src"
[2]=>
string(3) "abc"
}
[1]=>
array(3) {
[0]=>
string(10) " bla="123""
[1]=>
string(3) "bla"
[2]=>
string(3) "123"
}
}
Si es XHTML, su ejemplo es que solo necesita XML simple.
<?php
$input = ''<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny"/>'';
$sx = simplexml_load_string($input);
var_dump($sx);
?>
Salida:
object(SimpleXMLElement)#1 (1) {
["@attributes"]=>
array(3) {
["src"]=>
string(22) "/image/fluffybunny.jpg"
["title"]=>
string(16) "Harvey the bunny"
["alt"]=>
string(26) "a cute little fluffy bunny"
}
}
Solo 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()
porque este método puede manejar la sintaxis HTML y no obliga a que el documento de entrada sea XHTML. Estrictamente hablando, la conversión a SimpleXMLElement
no es necesaria, simplemente hace que usar xpath y los resultados de xpath sean más simples.
Tal vez esto te dará las respuestas correctas:
<img.*?(?:(?:/s+(src)="([^"]+)")|(?:/s+(alt)="([^"]+)")|(?:/s+(title)="([^"]+)")|(?:/s+[^/s]+))+.*/>
También puede probar SimpleXML si se garantiza que el HTML será XHTML: analizará el marcado por usted y podrá acceder a los atributos solo por su nombre. (También hay bibliotecas DOM si solo es HTML y no puede depender de la sintaxis XML.)
Usé preg_match para hacerlo.
En mi caso, tenía una cadena que contenía exactamente una etiqueta <img>
(y ninguna otra marca) que obtuve de Wordpress y estaba tratando de obtener el atributo src
para poder ejecutarlo a través de timthumb.
// get the featured image
$image = get_the_post_thumbnail($photos[$i]->ID);
// get the src for that image
$pattern = ''/src="([^"]*)"/'';
preg_match($pattern, $image, $matches);
$src = $matches[1];
unset($matches);
En el patrón para obtener el título o alt, simplemente puede usar $pattern = ''/title="([^"]*)"/'';
para tomar el título o $pattern = ''/title="([^"]*)"/'';
agarrar el alt. Tristemente, mi expresión regular no es lo suficientemente buena para agarrar los tres (alt / title / src) con un pase.
el siguiente código funcionó para mí en wordpress ...
extrae todas las fuentes de imagen del código
$search = "any html code with image tags";
preg_match_all( ''/src="([^"]*)"/'', $search, $matches);
if ( isset( $matches ) )
{
foreach ($matches as $match)
{
if(strpos($match[0], "src")!==false)
{
$res = explode("/"", $match[0]);
$image = parse_url($res[1], PHP_URL_PATH);
$xml .= " <image:image>/n";
$xml .= " <image:loc>".home_url().$image."</image:loc>/n";
$xml .= " <image:caption>".htmlentities($title)."</image:caption>/n";
$xml .= " <image:license>".home_url()."</image:license>/n";
$xml .= " </image:image>/n";
}
}
}
¡aclamaciones!
para un elemento, puede usar esta solución minimizada usando DOMDocument. Maneja las comillas ''y'' y también valida el html. La mejor práctica es usar bibliotecas existentes en lugar de su propia solución usando expresiones regulares.
$html = ''<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />'';
$attribute = ''src'';
$doc = new DOMDocument();
@$doc->loadHTML($html);
$attributeValue = @$doc->documentElement->firstChild->firstChild->attributes->getNamedItem($attribute)->value;
echo $attributeValue;
"]+>]+>/)?>"
esto extraerá una etiqueta de anclaje anidada con una etiqueta de imagen
$content = "<img src=''http://google.com/2af5e6ae749d523216f296193ab0b146.jpg'' width=''40'' height=''40''>";
$image = preg_match_all(''~<img rel="imgbot" remote="(.*?)" width="(.*?)" height="(.*?)" linktext="(.*?)" linkhref="(.*?)" src="(.*?)" />~is'', $content, $matches);
$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'');
}