복붙노트

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

PHP

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

나는 PHP DOM을 사용하고 있으며 주어진 클래스 이름을 가진 DOM 노드 내 요소를 가져 오려고합니다. 하위 요소를 가져 오는 가장 좋은 방법은 무엇입니까?

업데이트 : 나는 Mechanize for PHP를 사용하여 작업하기가 훨씬 쉬워졌습니다.

해결법

  1. ==============================

    1.업데이트 : Xpath 버전의 * [@ class ~ = 'my-class'] css selector

    업데이트 : Xpath 버전의 * [@ class ~ = 'my-class'] css selector

    그래서 hakre의 코멘트에 대한 아래의 코멘트에 대해 궁금해하고 Zend_Dom_Query의 코드를 살펴 보았습니다. 위의 선택기가 다음 xpath (컴파일되지 않음)로 컴파일 된 것 같습니다.

    [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 ')]");
    

    기본적으로, 우리가하는 일은 클래스 속성을 표준화하여 단일 클래스라도 공백으로 묶이고 전체 클래스 목록을 공백으로 묶는 것입니다. 그런 다음 검색 할 클래스에 공백을 추가하십시오. 이 방법으로 우리는 효과적으로 나의 클래스의 인스턴스만을 찾고 찾습니다.

    xpath 선택기를 사용 하시겠습니까?

    $dom = new DomDocument();
    $dom->load($filePath);
    $finder = new DomXPath($dom);
    $classname="my-class";
    $nodes = $finder->query("//*[contains(@class, '$classname')]");
    

    하나의 요소 유형 만있는 경우 *를 특정 태그로 대체 할 수 있습니다.

    매우 복잡한 선택기로이 작업을 많이해야하는 경우 CSS 선택기 구문 (la jQuery)을 지원하는 Zend Dom Query를 사용하는 것이 좋습니다.

    $finder = new Zend_Dom_Query($html);
    $classname = 'my-class';
    $nodes = $finder->query("*[class~=\"$classname\"]");
    
  2. ==============================

    2.젠드가없는 클래스의 innerhtml을 얻으려면 다음을 사용할 수 있습니다.

    젠드가없는 클래스의 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;
    
  3. ==============================

    3.나는 받아 들일 수있는 방법이 더 좋다고 생각하지만 이것은 잘 작동하는 것 같아.

    나는 받아 들일 수있는 방법이 더 좋다고 생각하지만 이것은 잘 작동하는 것 같아.

    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;
    }
    
  4. ==============================

    4.DomXPath 또는 Zend_Dom_Query를 사용하지 않고 다른 접근법이 있습니다.

    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".
    
  5. ==============================

    5.DOMDocument는 입력하기가 느리고 phpQuery는 메모리 누수 문제가 있습니다. 나는 다음과 같이 사용했다.

    DOMDocument는 입력하기가 느리고 phpQuery는 메모리 누수 문제가 있습니다. 나는 다음과 같이 사용했다.

    https://github.com/wasinger/htmlpagedom

    수업을 선택하려면 다음 단계를 따르세요.

    include 'includes/simple_html_dom.php';
    
    $doc = str_get_html($html);
    $href = $doc->find('.lastPage')[0]->href;
    

    이 도움이 다른 사람에게도 도움이되기를 바랍니다.

  6. from https://stackoverflow.com/questions/6366351/getting-dom-elements-by-classname by cc-by-sa and MIT license