PHP에서 HTML / XML을 구문 분석하고 처리하는 방법은 무엇입니까?



12 Answers

간단한 HTML DOM 파서를 사용 해라.

  • 아주 쉬운 방법으로 HTML을 조작 할 수있는 PHP 5+로 작성된 HTML DOM 파서입니다!
  • PHP 5 이상이 필요합니다.
  • 잘못된 HTML을 지원합니다.
  • jQuery와 같은 선택기로 HTML 페이지에서 태그를 찾으십시오.
  • HTML에서 내용을 한 줄로 추출합니다.
  • 다운로드


예 :

HTML 요소를 얻는 방법 :

// Create DOM from URL or file
$html = file_get_html('http://www.example.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>';


HTML 요소를 수정하는 방법 :

// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');

$html->find('div', 1)->class = 'bar';

$html->find('div[id=hello]', 0)->innertext = 'foo';

echo $html;


HTML에서 콘텐츠 추출 :

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;


스크래핑 Slashdot :

// Create DOM from URL
$html = file_get_html('http://slashdot.org/');

// Find all article blocks
foreach($html->find('div.article') as $article) {
    $item['title']     = $article->find('div.title', 0)->plaintext;
    $item['intro']    = $article->find('div.intro', 0)->plaintext;
    $item['details'] = $article->find('div.details', 0)->plaintext;
    $articles[] = $item;
}

print_r($articles);
Question

어떻게 HTML / XML을 파싱하고 그것으로부터 정보를 추출 할 수 있습니까?




phpQueryQueryPath 는 유창한 jQuery API를 복제하는 것과 매우 유사합니다. 그래서 PHP에서 HTML을 올바르게 구문 분석 할 있는 가장 쉬운 방법 중 두 가지입니다.

QueryPath 예제

기본적으로 먼저 HTML 문자열에서 쿼리 가능한 DOM 트리를 만듭니다.

 $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL

결과 객체에는 HTML 문서의 전체 트리 표현이 포함됩니다. DOM 메소드를 사용하여 탐색 할 수 있습니다. 그러나 일반적인 접근법은 jQuery와 같은 CSS 선택기를 사용하는 것입니다.

 $qp->find("div.classname")->children()->...;

 foreach ($qp->find("p img") as $img) {
     print qp($img)->attr("src");
 }

대부분 ->find() 대해 간단한 #id.class 또는 DIV 태그 선택자를 사용하려고합니다. 그러나 XPath 문을 사용할 수도 있는데 때로는 빠릅니다. 또한 ->children()->text() 및 특히 ->attr() 과 같은 일반적인 jQuery 메서드는 올바른 HTML 코드를 추출하는 것을 단순화합니다. (그리고 이미 SGML 엔티티가 디코딩되어 있습니다.)

 $qp->xpath("//div/p[1]");  // get first paragraph in a div

QueryPath는 또한 새로운 태그를 스트림에 삽입 ( ->append )하고 나중에 업데이트 된 문서를 출력하고 prettify ( ->writeHTML ) 할 수 있습니다. 조작 된 HTML뿐만 아니라 다양한 XML 언어 (네임 스페이스 포함)를 구문 분석 할 수 있으며 HTML 마이크로 포맷 (XFN, vCard)에서 데이터를 추출 할 수도 있습니다.

 $qp->find("a[target=_blank]")->toggleClass("usability-blunder");

.

phpQuery 또는 QueryPath?

일반적으로 QueryPath는 문서 조작에 더 적합합니다. phpQuery는 jQuery와 좀 더 가깝게 유사 AJAX (pseudo AJAX) 메소드 (HTTP 요청)를 구현한다. phpQuery는 (전체 기능이 적기 때문에) QueryPath보다 종종 빠르다고합니다.

차이점에 대한 더 자세한 정보 는 tagbyte.org의 wayback machine에서 비교해보십시오 . (원본 소스가 누락되어 인터넷 보관 링크가 있습니다. 예, 누락 된 페이지는 여전히 사람들을 찾을 수 있습니다.)

다음 은 포괄적 인 QueryPath 소개 입니다.

장점

  • 단순성과 신뢰성
  • 사용하기 쉬운 대안 ->find("a img, a object, div a")
  • 적절한 데이터 이스케이프 처리 (정규 표현식 grepping과 비교)



간단한 HTML DOM은 훌륭한 오픈 소스 파서입니다.

simplehtmldom.sourceforge

객체 지향 방식으로 DOM 요소를 처리하며, 새로운 반복은 비 규격 코드에 대해 많은 적용 범위를 갖고 있습니다. 또한 "find"함수와 같이 자바 스크립트에서 볼 수있는 것과 같은 훌륭한 함수가 있습니다.이 함수는 태그 이름의 모든 요소를 ​​반환합니다.

저는 이것을 여러 가지 도구로 사용하여 웹 페이지의 여러 유형에서 테스트했습니다.




FluidXML 을 사용하면 XPathCSS 선택기를 사용하여 XML을 쿼리하고 반복 할 수 있습니다.

$doc = fluidxml('<html>...</html>');

$title = $doc->query('//head/title')[0]->nodeValue;

$doc->query('//body/p', 'div.active', '#bgId')
        ->each(function($i, $node) {
            // $node is a DOMNode.
            $tag   = $node->nodeName;
            $text  = $node->nodeValue;
            $class = $node->getAttribute('class');
        });

https://github.com/servo-php/fluidxml




이것은 W3C XPath 기술의 좋은 작업 설명처럼 들립니다. <foo><bar><baz> elements 중첩 된 img 태그의 모든 href 속성을 반환하는 것과 같은 쿼리를 쉽게 표현할 수 <foo><bar><baz> elements . PHP 버프가 아니기 때문에 XPath가 어떤 형태로 제공되는지 알려주지는 못합니다. 외부 프로그램을 호출하여 HTML 파일을 처리 할 수있는 경우 XPath의 명령 줄 버전을 사용할 수 있어야합니다. 빠른 소개는 http://en.wikipedia.org/wiki/XPath를 참조하십시오.




PHPPowertools / DOM-Query 라는 라이브러리를 만들었습니다. jQuery와 마찬가지로 HTML5 및 XML 문서를 크롤링 할 수 있습니다.

후드 아래에서 CSS 선택기를 XPath 선택기로 변환하기 위해 symfony / DomCrawler 를 사용합니다. 하나의 객체를 다른 객체로 전달할 때도 항상 동일한 DomDocument를 사용하여 적절한 성능을 보장합니다.

사용 예 :

namespace PowerTools;

// Get file content
$htmlcode = file_get_contents('https://github.com');

// Define your DOMCrawler based on file string
$H = new DOM_Query($htmlcode);

// Define your DOMCrawler based on an existing DOM_Query instance
$H = new DOM_Query($H->select('body'));

// Passing a string (CSS selector)
$s = $H->select('div.foo');

// Passing an element object (DOM Element)
$s = $H->select($documentBody);

// Passing a DOM Query object
$s = $H->select( $H->select('p + p'));

// Select the body tag
$body = $H->select('body');

// Combine different classes as one selector to get all site blocks
$siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');

// Nest your methods just like you would with jQuery
$siteblocks->select('button')->add('span')->addClass('icon icon-printer');

// Use a lambda function to set the text of all site blocks
$siteblocks->text(function( $i, $val) {
    return $i . " - " . $val->attr('class');
});

// Append the following HTML to all site blocks
$siteblocks->append('<div class="site-center"></div>');

// Use a descendant selector to select the site's footer
$sitefooter = $body->select('.site-footer > .site-center');

// Set some attributes for the site's footer
$sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));

// Use a lambda function to set the attributes of all site blocks
$siteblocks->attr('data-val', function( $i, $val) {
    return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});

// Select the parent of the site's footer
$sitefooterparent = $sitefooter->parent();

// Remove the class of all i-tags within the site's footer's parent
$sitefooterparent->select('i')->removeAttr('class');

// Wrap the site's footer within two nex selectors
$sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');

[...]

지원되는 방법 :

  1. 명백한 이유로 '선택'으로 이름이 변경되었습니다.
  2. 'empty'는 PHP에서 예약어이기 때문에 'void'로 이름이 변경되었습니다.

노트 :

또한 PSR-0 호환 라이브러리 용 자체 구성 자동 로더가 라이브러리에 포함되어 있습니다. 포함 된 예제는 추가 구성없이 즉시 사용할 수 있습니다. 또는 작곡가와 함께 사용할 수도 있습니다.




네, 그 목적으로 simple_html_dom을 사용할 수 있습니다. 그러나 simple_html_dom과 함께 많은 작업을 해왔습니다. 특히 웹 스크래핑 (scrapping) 작업에 너무 취약한 것으로 나타났습니다. 그것은 기본적인 일을하지만 어쨌든 그것을 권하지는 않을 것입니다.

나는 결코 목적을 위해 컬을 사용하지 않았지만, 내가 배운 것은 컬이 훨씬 효율적으로 작업을 수행 할 수 있고 훨씬 더 견고하다는 것입니다.

이 링크를 잘 살펴보십시오. scraping-websites-with-curl




XML_HTMLSax 는 더 이상 유지되지 않아도 안정적입니다. 또 다른 옵션은 Html Tidy를 통해 HTML 을 파이프 처리 한 다음 표준 XML 도구로 파싱하는 것입니다.




HTML Tidy 와 같은 것을 사용하여 "손상된"HTML을 정리하고 HTML을 XHTML로 변환 할 수 있습니다. 그러면이를 XML 파서로 구문 분석 할 수 있습니다.




1a와 2의 경우 : 새로운 Symfony Componet 클래스 DOMCrawler ( DomCrawler )에 투표 할 것입니다. 이 클래스는 CSS 선택자와 비슷한 쿼리를 허용합니다. 이 프리젠 테이션을 실제 세계의 예를 보려면보십시오 : symfony2-world의 최신 뉴스 .

이 구성 요소는 독립 실행 형으로 설계되어 Symfony없이 사용할 수 있습니다.

유일한 단점은 PHP 5.3 이상에서만 작동한다는 것입니다.




우리는 전에 우리의 요구에 맞는 크롤러를 만들었습니다. 하루가 끝나면 보통 일을 가장 잘하는 것은 간단한 정규 표현식입니다. 위에 나열된 라이브러리가 작성된 이유로 적합하지만 원하는 대상을 알고 있으면 정규식이 더 안전한 방법입니다. 유효하지 않은 HTML / XHTML 구조도 처리 할 수 ​​있습니다.로드되지 않으면 실패합니다 대부분의 파서를 통해




GB 파일을 쉽게 처리 할 수있는 범용 XML 파서를 작성했습니다. XMLReader를 기반으로하며 사용하기가 매우 쉽습니다.

$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
    echo $tag->field1;
    echo $tag->field2->subfield1;
}

github repo가 ​​있습니다 : XmlExtractor




고급 HTML 돔 은 동일한 인터페이스를 제공하는 단순한 HTML DOM 대체품이지만 관련 메모리 문제가 발생하지 않는 DOM 기반입니다.

또한 jQuery 확장을 포함한 완벽한 CSS 지원을 제공합니다.



Related