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


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을 파싱하고 그것으로부터 정보를 추출 할 수 있습니까?




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




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

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

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




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




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

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

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




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




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

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




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




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

simplehtmldom.sourceforge

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

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




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




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




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