PHP를 사용하여 HTML에서 IMG SRC, 제목 및 ALT를 추출하는 방법은 무엇입니까?
-
02-07-2019 - |
문제
내 웹 사이트에있는 모든 이미지에 제목과 대체 표현이 표시되는 페이지를 만들고 싶습니다.
나는 이미 모든 HTML 파일을 찾고로드하기위한 작은 프로그램을 이미 작성했지만 이제는 추출하는 방법에 갇혀 있습니다. src
, title
그리고 alt
이 HTML에서 :
<img SRC="/image/fluffybunny.jpg" 제목="Harvey the bunny" 대체="a cute little fluffy bunny" />
나는 이것이 약간의 정규식으로 이루어져야한다고 생각하지만, 태그의 순서가 다를 수 있고, 그들 모두가 필요하기 때문에, 나는 이것을 우아한 방식으로 구문 분석하는 방법을 실제로 모른다 (나는 하드 숯으로 할 수있다. char way, 그러나 그것은 고통 스럽습니다).
해결책
편집 : 이제 더 잘 알았습니다
이런 종류의 문제를 해결하기 위해 regexp를 사용하는 것은입니다 나쁜 생각 그리고 인재 할 수없고 신뢰할 수없는 코드로 이어질 것입니다. 더 잘 사용합니다 HTML 파서.
Regexp를 사용한 솔루션
이 경우 프로세스를 두 부분으로 나누는 것이 좋습니다.
- 모든 IMG 태그를 얻으십시오
- 메타 데이터를 추출하십시오
나는 당신의 문서가 XHTML이 엄격하지 않다고 가정하므로 XML 파서를 사용할 수 없습니다. 예 :이 웹 페이지 소스 코드와 함께 :
/* 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)" />
[...]
)
)
그런 다음 모든 IMG 태그 속성을 루프로 얻습니다.
$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"
)
)
[..]
)
)
Regexps는 CPU 집중적 이므로이 페이지를 캐시 할 수 있습니다. 캐시 시스템이없는 경우 사용하여 직접 조정할 수 있습니다. OB_START 및 텍스트 파일에서로드 / 저장.
이 물건은 어떻게 작동합니까?
먼저, 우리는 사용합니다 preg_ match_ 모두, 모든 문자열이 패턴과 일치하고 세 번째 매개 변수에 넣는 함수.
regexps :
<img[^>]+>
모든 HTML 웹 페이지에 적용합니다. 읽을 수 있습니다 "로 시작하는 모든 문자열" "<img
", 비"> "char를 포함하고>로 끝납니다..
(alt|title|src)=("[^"]*")
각 IMG 태그에 연속적으로 적용합니다. 읽을 수 있습니다 "alt", "title"또는 "src", 그런 다음 "=", a ' ",' '', '' ''로 끝나는 모든 문자열은 '' ''로 끝납니다. () 사이의 문자열.
마지막으로, regexps를 다룰 때마다 빠르게 테스트 할 수있는 좋은 도구를 갖는 것이 편리합니다. 이것을 확인하십시오 온라인 Regexp 테스터.
편집 : 첫 번째 주석에 대한 답변.
단일 인용문을 사용하는 사람들에 대해 생각하지 않았다는 것은 사실입니다.
글쎄, 만 사용하는 경우 '만 사용하면'by '를 교체하십시오.
둘 다 섞으면. 먼저 자신을 때려야합니다 :-), 그런 다음 [^"]를 대체하기 위해 ("| ') 대신 ( "|')와 [^Ø]를 사용하려고 노력하십시오.
다른 팁
$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');
}
작업에 PHP의 XML 기능을 사용하는 작은 예를 제공하기 위해서는 다음과 같습니다.
$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'];
}
나는 그것을 사용했다 DOMDocument::loadHTML()
이 메소드는 HTML-Syntax에 대처할 수 있고 입력 문서가 XHTML이되지 않기 때문에 방법. 엄밀히 말하면 a 로의 전환 SimpleXMLElement
필요하지 않습니다. XPath를 사용하고 XPath 결과를 더 간단하게 만듭니다.
XHTML 인 경우 예제는 SimpleXML 만 필요합니다.
<?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);
?>
산출:
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"
}
}
스크립트는 다음과 같이 편집해야합니다
foreach( $result[0] as $img_tag)
preg_match_all 배열의 배열이기 때문에
당신은 사용할 수 있습니다 simplehtmldom. 대부분의 jQuery 선택기는 SimpleHtmlom에서 지원됩니다. 예는 다음과 같습니다
// 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>';
나는 preg_match를 사용하여 그것을 사용했습니다.
제 경우에는 정확히 하나를 포함하는 문자열이있었습니다. <img>
WordPress에서 얻은 태그 (및 다른 마크 업은) src
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);
제목이나 alt를 가져 오려는 패턴에서 단순히 사용할 수 있습니다. $pattern = '/title="([^"]*)"/';
제목을 잡으려면 또는 $pattern = '/title="([^"]*)"/';
Alt를 잡으려면. 안타깝게도 내 동정형은 하나의 패스로 세 가지 (Alt/Title/SRC)를 모두 잡기에 충분하지 않습니다.
다음은 비슷한 목적을 위해 위의 모든 정보에서 함께 모은 PHP 기능입니다. 즉, 이미지 태그 너비와 길이 속성을 즉시 조정하는 것입니다.
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;
}
PHP의 해결책은 다음과 같습니다.
QueryPath를 다운로드 한 다음 다음과 같이 수행하십시오.
$doc= qp($myHtmlDoc);
foreach($doc->xpath('//img') as $img) {
$src= $img->attr('src');
$title= $img->attr('title');
$alt= $img->attr('alt');
}
그게 다야, 끝났어!
이 페이지에서 DOM 파서를 사용하는 것이 불필요한 오버 헤드라고 불평하는 많은 의견을 읽었습니다. 글쎄, 그것은 단순한 Regex 호출보다 더 비쌀 수 있지만 OP는 IMG 태그의 속성 순서에 대한 통제가 없다고 진술했습니다. 이 사실은 불필요한 정규 패턴 컨볼 루션으로 이어집니다. 그 외에도 Dom Parser를 사용하면 가독성, 유지 관리 및 DOM 인식의 추가 이점이 제공됩니다 (Regex는 Dom-Aware가 아닙니다).
나는 Regex를 좋아하고 많은 Regex 질문에 대답하지만, 유효한 HTML을 다룰 때는 파서에 대한 재배치가 거의 없습니다.
아래 데모에서 인용이 혼합 된 (그리고 전혀 인용하지 않음) 순서로 IMG 태그 속성을 쉽게 처리하는 방법을 참조하십시오. 또한 타겟팅 된 속성이없는 태그는 전혀 파괴적이지 않습니다. 빈 문자열은 값으로 제공됩니다.
코드 : (데모)
$test = <<<HTML
<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />
<img src='/image/pricklycactus.jpg' title='Roger the cactus' alt='a big green prickly cactus' />
<p>This is irrelevant text.</p>
<img alt="an annoying white cockatoo" title="Polly the cockatoo" src="/image/noisycockatoo.jpg">
<img title=something src=somethingelse>
HTML;
libxml_use_internal_errors(true); // silences/forgives complaints from the parser (remove to see what is generated)
$dom = new DOMDocument();
$dom->loadHTML($test);
foreach ($dom->getElementsByTagName('img') as $i => $img) {
echo "IMG#{$i}:\n";
echo "\tsrc = " , $img->getAttribute('src') , "\n";
echo "\ttitle = " , $img->getAttribute('title') , "\n";
echo "\talt = " , $img->getAttribute('alt') , "\n";
echo "---\n";
}
산출:
IMG#0:
src = /image/fluffybunny.jpg
title = Harvey the bunny
alt = a cute little fluffy bunny
---
IMG#1:
src = /image/pricklycactus.jpg
title = Roger the cactus
alt = a big green prickly cactus
---
IMG#2:
src = /image/noisycockatoo.jpg
title = Polly the cockatoo
alt = an annoying white cockatoo
---
IMG#3:
src = somethingelse
title = something
alt =
---
이 기술을 전문 코드로 사용하면 깨끗한 대본, 딸꾹질이 적고 다른 곳에서 일하기를 원하는 동료가 적습니다.