programing tip

클래스 이름으로 DOM 요소 가져 오기

itbloger 2020. 7. 17. 20:56
반응형

클래스 이름으로 DOM 요소 가져 오기


내가 사용하고 PHP DOM을 나는 주어진 클래스 이름을 가지고 DOM 노드 내의 요소를 얻기 위해 노력하고있어. 그 하위 요소를 얻는 가장 좋은 방법은 무엇입니까?

업데이트 :Mechanize 작업하기가 훨씬 쉬운 PHP를 사용 했습니다.


업데이트 : *[@class~='my-class']CSS 선택기의 Xpath 버전

그래서 hakre의 의견에 대한 응답으로 아래의 의견을 읽은 후 궁금해하고 코드를 살펴 보았습니다 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')]");

하나의 요소 유형 인 *경우 특정 태그 이름으로 바꿀 수 있습니다 .

매우 복잡한 선택기 로이 작업을 많이 수행 해야하는 경우 Zend_Dom_QueryCSS 선택기 구문 (la 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.

Based on dav's original function, I wrote the following function that returns all the children of the parent node whose tag and class match the parameters.

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;
}

suppose you have a variable $html the following 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>

use of getElementsByClass is as simple as:

$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 is slow to type and phpQuery has bad memory leak issues. I ended up using:

https://github.com/wasinger/htmlpagedom

To select a class:

include 'includes/simple_html_dom.php';

$doc = str_get_html($html);
$href = $doc->find('.lastPage')[0]->href;

I hope this helps someone else as well

참고URL : https://stackoverflow.com/questions/6366351/getting-dom-elements-by-classname

반응형