PHP DOM을 사용하고 있으며 DOM 노드 내에서 특정 클래스 이름을 가진 요소를 가져오려고 합니다.그 서브 엘리먼트를 입수하는 가장 좋은 방법은 무엇입니까?
업데이트: 사용되었습니다.Mechanize
PHP를 사용하기 쉽게 되어 있습니다.
질문에 대한 답변
업데이트: Xpath 버전*[@class~='my-class']
css 셀렉터
그래서 하크레의 코멘트에 대한 아래의 코멘트를 듣고 궁금해서 뒤에 있는 코드를 조사했습니다.Zend_Dom_Query
위의 셀렉터는 다음 xpath(테스트되지 않음)로 컴파일되어 있는 것 같습니다.
[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
따라서 PHP는 다음과 같습니다.
$dom = new DomDocument(); $dom->load($filePath); $finder = new DomXPath($dom); $classname="my-class"; $nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
기본적으로, 여기서 우리가 하는 모든 일은,class
단일 클래스도 공백으로 제한되고 전체 클래스 목록이 공백으로 제한되도록 속성을 지정합니다.그런 다음 찾고 있는 클래스를 공백으로 추가합니다.이 방법을 통해 델은 효과적인 방법으로 델이 찾고 있는 것은my-class
.
xpath 셀렉터를 사용하시겠습니까?
$dom = new DomDocument(); $dom->load($filePath); $finder = new DomXPath($dom); $classname="my-class"; $nodes = $finder->query("//*[contains(@class, '$classname')]");
1가지 유형의 요소만 있는 경우 이 요소를 교환할 수 있습니다.*
특정 타그네임과 함께.
매우 복잡한 셀렉터를 사용하여 이 작업을 많이 수행해야 하는 경우 가 CSS 셀렉터 구문(일명 jQuery)을 지원하는 것을 권장합니다.
$finder = new Zend_Dom_Query($html); $classname = 'my-class'; $nodes = $finder->query("*[class~="$classname"]");
zend를 사용하지 않고 클래스의 innerhtml을 가져오려면 다음을 사용할 수 있습니다.
$dom = new DomDocument(); $dom->load($filePath); $classname = 'main-article'; $finder = new DomXPath($dom); $nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]"); $tmp_dom = new DOMDocument();
foreach ($nodes as $node)
{
$tmp_dom->appendChild($tmp_dom->importNode($node,true));
} $innerHTML.=trim($tmp_dom->saveHTML());
echo $innerHTML;
인정받는 방법이 더 낫다고 생각하지만, 이것도 효과가 있을 것 같아요.
function getElementByClass(&$parentNode, $tagName, $className, $offset = 0) {
$response = false;
$childNodeList = $parentNode->getElementsByTagName($tagName);
$tagCount = 0;
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
if ($tagCount == $offset) {
$response = $temp;
break;
}
$tagCount++;
}
}
return $response; }
다른 접근법도 있습니다.DomXPath
또는Zend_Dom_Query
.
dav의 원래 함수를 바탕으로 태그와 클래스가 파라미터와 일치하는 상위 노드의 모든 자식을 반환하는 다음 함수를 작성했습니다.
function getElementsByClass(&$parentNode, $tagName, $className) {
$nodes=array();
$childNodeList = $parentNode->getElementsByTagName($tagName);
for ($i = 0; $i < $childNodeList->length; $i++) {
$temp = $childNodeList->item($i);
if (stripos($temp->getAttribute('class'), $className) !== false) {
$nodes[]=$temp;
}
}
return $nodes; }
변수가 있다고 가정합니다.$html
다음 HTML:
<html>
<body>
<div id="content_node">
<p class="a">I am in the content node.</p>
<p class="a">I am in the content node.</p>
<p class="a">I am in the content node.</p>
</div>
<div id="footer_node">
<p class="a">I am in the footer node.</p>
</div>
</body> </html>
의 사용.getElementsByClass
다음과 같이 심플합니다.
$dom = new DOMDocument('1.0', 'utf-8'); $dom->loadHTML($html); $content_node=$dom->getElementById("content_node");
$div_a_class_nodes=getElementsByClass($content_node, 'div', 'a');//will contain the three nodes under "content_node".
DOMDocument 입력이 느리고 phpQuery에 메모리 누수 문제가 있습니다.사용 결과:
https://github.com/wasinger/htmlpagedom
클래스를 선택하려면:
include 'includes/simple_html_dom.php';
$doc = str_get_html($html); $href = $doc->find('.lastPage')[0]->href;
이게 다른 사람에게도 도움이 됐으면 좋겠어요.