どのようにしてHTML / XMLを解析し、そこから情報を抽出できますか?
どのようにしてHTML / XMLを解析し、そこから情報を抽出できますか?
回答:
PHPにバンドルされているので、ネイティブXML拡張機能の 1つを使用することを好みます。これらは通常、すべてのサードパーティライブラリよりも高速で、マークアップに対して必要なすべての制御を提供します。
DOM拡張機能を使用すると、PHP 5のDOM APIを介してXMLドキュメントを操作できます。これは、W3Cのドキュメントオブジェクトモデルコアレベル3の実装です。ドキュメントのコンテンツ、構造、スタイル。
DOMは、実世界の(壊れた)HTMLを解析および変更でき、XPathクエリを実行できます。libxmlに基づいています。
DOMで生産的になるには少し時間がかかりますが、その時間はIMOに値するものです。DOMは言語に依存しないインターフェースであるため、多くの言語で実装が見つかるので、プログラミング言語を変更する必要がある場合は、その言語のDOM APIの使用方法をすでに知っていることでしょう。
基本的な使用例はA要素のhref属性の取得にあり、一般的な概念の概要はphpのDOMDocumentにあります。
DOM拡張機能の使用方法はStackOverflowで広くカバーされているため、それを使用することを選択した場合、発生した問題のほとんどはStack Overflowを検索/参照することで解決できると確信できます。
XMLReader拡張機能は、XMLプルパーサーです。リーダーは、ドキュメントストリームを先に進み、途中の各ノードで停止するカーソルとして機能します。
XMLReaderは、DOMと同様にlibxmlに基づいています。私はHTMLパーサーモジュールをトリガーする方法を知らないので、壊れたHTMLを解析するためにXMLReaderを使用する可能性は、libxmlのHTMLパーサーモジュールを使用するように明示的に指示できるDOMを使用するよりも堅牢ではない可能性があります。
基本的な使用例は、phpを使用してh1タグからすべての値を取得するときに見つけることができます
この拡張機能を使用すると、XMLパーサーを作成してから、さまざまなXMLイベントのハンドラーを定義できます。各XMLパーサーには、調整可能ないくつかのパラメーターもあります。
XMLパーサーライブラリもlibxmlに基づいており、SAXスタイルのXMLプッシュパーサーを実装しています。DOMやSimpleXMLよりもメモリ管理には適しているかもしれませんが、XMLReaderによって実装されたプルパーサーよりも操作が難しくなります。
SimpleXML拡張機能は、XMLを通常のプロパティセレクターや配列イテレーターで処理できるオブジェクトに変換するための非常にシンプルで使いやすいツールセットを提供します。
SimpleXMLは、HTMLが有効なXHTMLであることがわかっている場合のオプションです。壊れたHTMLを解析する必要がある場合は、SimpleXmlを使用しないでください。窒息するからです。
基本的な使用例は、XMLファイルのノードとノードの値をCRUDする単純なプログラムにあります。PHP マニュアルには、その他にも多くの例があります。
サードパーティのlibを使用したい場合は、文字列の解析ではなく、実際にDOM / libxmlを実際に使用するlibを使用することをお勧めします。
FluentDOMは、jQueryのような流暢なXMLインターフェイスをPHPのDOMDocumentに提供します。セレクターはXPathまたはCSSで記述されます(CSSからXPathへのコンバーターを使用)。現在のバージョンでは、DOM実装標準インターフェースを拡張し、DOM Living Standardの機能を追加しています。FluentDOMは、JSON、CSV、JsonML、RabbitFishなどの形式をロードできます。Composer経由でインストールできます。
Wa72 \ HtmlPageDom`は、HTMLドキュメントを簡単に操作するためのPHPライブラリです。DOMツリーをトラバースするにはSymfony2コンポーネントのDomCrawlerが必要であり、HTMLドキュメントのDOMツリーを操作するメソッドを追加して拡張します。
phpQueryは、PHP5で記述されたjQuery JavaScriptライブラリに基づくサーバーサイドのチェーン可能なCSS3セレクター駆動型ドキュメントオブジェクトモデル(DOM)APIであり、追加のコマンドラインインターフェイス(CLI)を提供します。
次も参照してください:https : //github.com/electrolinux/phpquery
Zend_Domは、DOMドキュメントと構造を操作するためのツールを提供します。現在、Zend_Dom_Queryを提供しています。これは、XPathセレクターとCSSセレクターの両方を利用してDOMドキュメントをクエリするための統合インターフェースを提供します。
QueryPathは、XMLおよびHTMLを操作するためのPHPライブラリです。ローカルファイルだけでなく、Webサービスやデータベースリソースでも機能するように設計されています。jQueryインターフェースの多く(CSSスタイルのセレクターを含む)を実装しますが、サーバー側で使用するために大幅に調整されています。Composer経由でインストールできます。
fDOMDocumentは、標準のDOMを拡張して、PHPの警告や通知ではなく、エラーが発生した場合に常に例外を使用します。また、便利なように、またDOMの使用を簡略化するために、さまざまなカスタムメソッドとショートカットを追加しています。
sabre / xmlは、XMLReaderクラスとXMLWriterクラスをラップおよび拡張して、単純な「xml to object / array」マッピングシステムとデザインパターンを作成するライブラリです。XMLの書き込みと読み取りはシングルパスであるため、高速で、大きなxmlファイルに必要なメモリが少なくて済みます。
FluidXMLは、簡潔で流暢なAPIでXMLを操作するためのPHPライブラリです。XPathと流暢なプログラミングパターンを活用して、楽しく効果的なものにします。
DOM / libxmlをベースに構築することの利点は、ネイティブ拡張に基づいているため、すぐに使用できる優れたパフォーマンスが得られることです。ただし、すべてのサードパーティライブラリがこの方法を使用するわけではありません。それらのいくつかは以下にリストされています
- PHP5 +で記述されたHTML DOMパーサーを使用すると、HTMLを非常に簡単に操作できます。
- PHP 5以降が必要です。
- 無効なHTMLをサポートします。
- jQueryのようなセレクターを使用してHTMLページ上のタグを検索します。
- HTMLからコンテンツを1行で抽出します。
通常、このパーサーはお勧めしません。コードベースは恐ろしいものであり、パーサー自体はかなり遅く、メモリを大量に消費します。すべてのjQueryセレクター(子セレクターなど)が使用できるわけではありません。libxmlベースのライブラリはどれも、これを簡単に上回ります。
PHPHtmlParserは、jQueryなどのcssセレクターを使用してタグを選択できる、シンプルで柔軟なhtmlパーサーです。目標は、HTMLが有効かどうかに関係なく、HTMLをすばやく簡単にスクラップする方法を必要とするツールの開発を支援することです。このプロジェクトは元々sunra / php-simple-html-dom-parserによってサポートされていましたが、サポートが停止しているようですので、このプロジェクトは彼の以前の仕事の私の適応です。
繰り返しますが、このパーサーはお勧めしません。CPU使用率が高いと、かなり遅くなります。また、作成されたDOMオブジェクトのメモリをクリアする機能もありません。これらの問題は、特にネストされたループで拡大します。ドキュメント自体は不正確でスペルが間違っており、4月16日以降の修正に対する応答はありません。
- ユニバーサルトークナイザーとHTML / XML / RSS DOMパーサー
- 要素とその属性を操作する機能
- 無効なHTMLおよびUTF8をサポート
- 要素に対して高度なCSS3のようなクエリを実行できます(jQueryなどの名前空間がサポートされています)
- HTMLビューティファイヤー(HTML Tidyなど)
- CSSとJavaScriptを縮小
- 属性のソート、大文字と小文字の変更、インデントの修正など。
- 拡張可能
- 現在の文字/トークンに基づくコールバックを使用してドキュメントを解析する
- 操作を簡単なオーバーライドのために小さな機能に分割
- 速くて簡単
使用したことはありません。それが良いかどうかはわかりません。
上記を使用してHTML5を解析できますが、HTML5で許可されているマークアップが原因で問題が発生する可能性があります。したがって、HTML5の場合、次のような専用パーサーの使用を検討してください。
WHATWG HTML5仕様に基づくHTMLパーサーのPythonおよびPHP実装で、主要なデスクトップWebブラウザーとの互換性を最大限に高めます。
HTML5が完成すると、専用のパーサーが増える可能性があります。W3の「How-To for html 5 parsing」というブログポストもチェックする価値があります。
PHPをプログラミングしたくない場合は、Webサービスを使用することもできます。一般に、これらのユーティリティはほとんど見つかりませんでしたが、それは私と私の使用例にすぎません。
ScraperWikiの外部インターフェイスを使用すると、Webまたは独自のアプリケーションで使用する形式でデータを抽出できます。スクレーパーの状態に関する情報を抽出することもできます。
最後に推奨される方法として、正規表現を使用してHTMLからデータを抽出できます。一般に、HTMLで正規表現を使用することはお勧めしません。
マークアップに一致させるためにWeb上で見つかるスニペットのほとんどは壊れやすいものです。ほとんどの場合、これらは特定のHTMLに対してのみ機能します。どこかに空白を追加したり、タグの属性を追加または変更したりするなど、小さなマークアップを変更すると、正しく記述されていない場合にRegExが失敗する可能性があります。HTMLでRegExを使用する前に、何をしているかを知っておく必要があります。
HTMLパーサーはすでにHTMLの構文規則を知っています。正規表現は、作成する新しいRegExごとに教える必要があります。場合によってはRegExで問題ありませんが、実際にはユースケースによって異なります。
より信頼性の高いパーサーを作成できますが、前述のライブラリが既に存在し、これに対してはるかに優れた作業を行う場合、正規表現を使用して完全で信頼性の高いカスタムパーサーを作成するのは時間の無駄です。
Html The Cthulhu Wayの解析も参照してください。
お金を使いたいなら、
私はPHPアーキテクトや作者とは関係ありません。
// 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>';
// 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;
// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;
// 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);
DOMDocument-> loadHTML()を使用するだけで完了です。libxmlのHTML解析アルゴリズムは非常に優れて高速であり、一般的な考えに反して、不正な形式のHTMLには影響しません。
なぜ正規表現を使用すべきではなく、いつ使用すべきですか?
まず、よくある誤解:正規表現はHTML を「解析」するためのものではありません。ただし、正規表現はデータを「抽出」できます。抽出は、彼らのために作られたものです。適切なSGMLツールキットまたはベースラインXMLパーサーに対する正規表現のHTML抽出の主な欠点は、構文上の労力と信頼性のばらつきです。
ある程度信頼できるHTML抽出正規表現を作成することを検討してください。
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
単純なphpQueryまたは同等のQueryPathよりも読みにくくなります。
$div->find(".stationcool a")->attr("title");
ただし、それらが役立つ特定のユースケースがあります。
<!--
、抽出に役立つアンカーになる場合があります。特に、疑似HTMLのバリエーション<$var>
やSGMLの残留物は、正規表現で簡単に調整できます。正規表現/<!--CONTENT-->(.+?)<!--END-->/
を使用してHTMLのスニペットを事前に抽出し、より簡単なHTMLパーサーのフロントエンドを使用して残りを処理することをお勧めすることもあります。
注:私は実際にこのアプリを持っています。XML解析と正規表現を交互に使用しています。ちょうど先週、PyQueryの解析が失敗し、正規表現はまだ機能していました。はい、奇妙で、私はそれを自分で説明することはできません。しかし、それは起こりました。
だから、実際の考慮事項をregex = evil memeと一致しないという理由だけで投票しないでください。しかし、これもあまり投票しないでください。これは、このトピックの補足にすぎません。
DOMComment
コメントを読むことができるので、そのために正規表現を使用する理由はありません。
DOM
はlibxmlを使用し、libxmlは HTMLをロードするときに使用される個別のHTMLパーサーモジュールを持っているloadHTML()
ため、「実世界」(壊れた読み取り)のHTMLを非常に多くロードできます。
phpQueryとQueryPathは、流暢なjQuery APIの複製において非常に似ています。これが、PHPでHTML を適切に解析する最も簡単な方法の2つである理由でもあります。
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");
}
ほとんどの場合、あなたは簡単に使用したい#id
と.class
かDIV
のタグセレクタを->find()
。ただし、XPathステートメントを使用することもできます。また、典型的なjQueryメソッドは、適切なHTMLスニペットのような->children()
、->text()
特にその->attr()
抽出を簡単にします。(そして既にそれらのSGMLエンティティがデコードされています。)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPathを使用すると、新しいタグをストリームに挿入し(->append
)、後で出力し、更新されたドキュメントをきれいにすることもできます(->writeHTML
)。不正な形式のHTMLだけでなく、さまざまなXML方言(名前空間付き)も解析でき、HTMLマイクロフォーマット(XFN、vCard)からデータを抽出することもできます。
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
。
phpQueryまたはQueryPath?
通常、QueryPathはドキュメントの操作に適しています。phpQueryは、jQueryにさらによく似たいくつかの疑似AJAXメソッド(HTTPリクエストのみ)も実装します。多くの場合、phpQueryはQueryPathよりも高速であると言われています(全体的な機能が少ないため)。
違いの詳細については、tagbyte.orgのウェイバックマシンでのこの比較を参照してください。(元のソースがなくなっていたので、ここにインターネットアーカイブリンクがあります。はい、行方不明のページを見つけることができます)。
そして、これが包括的なQueryPathの紹介です。
メリット
->find("a img, a object, div a")
シンプルなHTML DOMは、優れたオープンソースのパーサーです。
オブジェクト指向の方法でDOM要素を処理し、新しいイテレーションは非準拠コードを多くカバーします。また、JavaScriptに見られるような素晴らしい関数もあります。たとえば、「find」関数は、そのタグ名の要素のすべてのインスタンスを返します。
私はこれをいくつかのツールで使用し、さまざまな種類のWebページでテストしてきました。
1aと2の場合:新しいSymfony ComponetクラスDOMCrawler(DomCrawler)に投票します。このクラスでは、CSSセレクターと同様のクエリを使用できます。実際の例については、このプレゼンテーションをご覧ください:news-of-the-symfony2-world。
コンポーネントはスタンドアロンで動作するように設計されており、Symfonyなしで使用できます。
唯一の欠点は、PHP 5.3以降でのみ機能することです。
ちなみに、これは一般にスクリーンスクレイピングと呼ばれています。これに使用したライブラリはSimple HTML Dom Parserです。
PHP Simple HTML DOM Parserをお勧めします。
それは本当に素晴らしい機能を持っています:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
これは、W3C XPathテクノロジーの優れたタスクの説明のようです。「にネストされているタグのすべてのhref
属性を返す」のようなクエリは簡単に表現できます。PHPの愛好家ではないため、XPathがどのような形で利用できるかはわかりません。外部プログラムを呼び出してHTMLファイルを処理できる場合は、コマンドラインバージョンのXPathを使用できるはずです。簡単な紹介については、http://en.wikipedia.org/wiki/XPathを参照してください。img
<foo><bar><baz> elements
はい、目的のためにsimple_html_domを使用できます。ただし、simple_html_domを使用して、特にWebの廃棄についてかなり作業し、脆弱性が高すぎることがわかりました。それは基本的な仕事をしますが、とにかくお勧めしません。
私はその目的でcurlを使用したことはありませんが、curlがより効率的に作業を行うことができ、はるかに堅固であることを学びました。
親切にこのリンクをチェックしてください:scraping-websites-with-curl
QueryPathは適切ですが、「追跡状態」の原因に注意してください。意味がわからない場合は、何が起こっているのか、なぜコードが機能しないのかを調べるためにデバッグに多くの時間を費やす可能性があります。
これは、結果セットの各呼び出しがオブジェクトの結果セットを変更することを意味します。jlinkでは、各リンクが新しいセットであり、クエリからの結果である単一のセットがあり、各関数呼び出しが変更されます。その単一のセット。
jqueryのような動作を実現するには、filter / modify like操作を実行する前に分岐する必要があります。つまり、jqueryで発生することをより厳密に反映します。
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
これでinput[name='forename']
、元のクエリの結果セットが含まれなくなりました。これにより"div p"
、QueryPathはフィルターを追跡し、結果を変更してオブジェクトに保存するすべてのものを追跡します。代わりにこれを行う必要があります
$forename = $results->branch()->find("input[name='forname']")
その後$results
は変更されず、結果セットを何度も再利用できます。おそらく、より知識のある誰かがこれを少しクリアできるかもしれませんが、基本的には、私が見つけたものからはこのようなものです。
Advanced Html Domは、同じインターフェースを提供する単純なHTML DOMの代替品ですが、DOMベースであるため、関連するメモリの問題は発生しません。
jQueryを含む完全なCSSサポートも備えています拡張機能ます。
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リポジトリです:XmlExtractor
PHPPowertools / DOM-Queryという名前のライブラリを作成しました。これにより、jQueryと同じようにHTML5およびXML文書をクロールできます。
内部的には、CSSセレクターからXPathセレクターへの変換にsymfony / DomCrawlerを使用します。適切なパフォーマンスを確保するために、1つのオブジェクトを別のオブジェクトに渡す場合でも、常に同じ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>');
[...]
ライブラリには、PSR-0互換ライブラリ用の独自のゼロ設定オートローダーも含まれています。含まれている例は、追加の構成なしでそのまま使用できます。または、composerで使用することもできます。
XML_HTMLSax
かなり安定している-それが維持されなくなったとしても。別のオプションは、HTML Tidyを介してHTMLをパイプ処理し、標準のXMLツールで解析することです。
HTML / XML DOMを処理する方法はたくさんありますが、そのほとんどはすでに言及されています。したがって、私はそれらを自分でリストしようとはしません。
私が個人的にDOM拡張機能を使用することを好むことと、その理由を追加したいだけです。
私はCSSセレクタを使用する能力を欠場しながらDOMDocument
サブクラス化:この機能を追加するためではなく、簡単で便利な方法がありDOMDocument
かつJS-などの追加querySelectorAll
およびquerySelector
方法あなたのサブクラスには。
セレクターの解析には、Symfonyフレームワークの非常に最小限のCssSelectorコンポーネントを使用することをお勧めします。このコンポーネントは、CSSセレクターをXPathセレクターに変換するだけです。XPath セレクターをにフィードして、対応するノードリストを取得できます。DOMXpath
次に、この(まだ非常に低レベルの)サブクラスを、より高レベルのクラスの基礎として使用できます。非常に特定のタイプのXMLを解析するか、jQueryのような動作を追加します。
以下のコードは、私のDOM-Queryライブラリーをそのまま使用したもので、私が説明した手法を使用しています。
HTML解析の場合:
namespace PowerTools;
use \Symfony\Component\CssSelector\CssSelector as CssSelector;
class DOM_Document extends \DOMDocument {
public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
parent::__construct($version, $encoding);
if ($doctype && $doctype === 'html') {
@$this->loadHTML($data);
} else {
@$this->loadXML($data);
}
}
public function querySelectorAll($selector, $contextnode = null) {
if (isset($this->doctype->name) && $this->doctype->name == 'html') {
CssSelector::enableHtmlExtension();
} else {
CssSelector::disableHtmlExtension();
}
$xpath = new \DOMXpath($this);
return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
}
[...]
public function loadHTMLFile($filename, $options = 0) {
$this->loadHTML(file_get_contents($filename), $options);
}
public function loadHTML($source, $options = 0) {
if ($source && $source != '') {
$data = trim($source);
$html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
$data_start = mb_substr($data, 0, 10);
if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
$html5->loadHTML($data);
} else {
@$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
$t = $html5->loadHTMLFragment($data);
$docbody = $this->getElementsByTagName('body')->item(0);
while ($t->hasChildNodes()) {
$docbody->appendChild($t->firstChild);
}
}
}
}
[...]
}
SymfonyのCssSelectorコンポーネントを作成する決定とその使用方法については、Symfonyの作成者であるFabien PotencierによるCSSセレクターを使用したXMLドキュメントの解析も参照してください。
ではFluidXMLあなたが使用してクエリを実行し、反復XMLができたXPathやCSSセレクタを。
$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');
});
JSONと3行のXMLからの配列:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
だだ!
正規表現でHTMLを解析しない理由はいくつかあります。ただし、生成されるHTMLを完全に制御できる場合は、単純な正規表現を使用できます。
上記は、正規表現によってHTMLを解析する関数です。この関数は非常に敏感で、HTMLが特定のルールに従うことを要求しますが、多くのシナリオで非常にうまく機能することに注意してください。単純なパーサーが必要で、ライブラリーをインストールしたくない場合は、これを試してみてください。
function array_combine_($keys, $values) {
$result = array();
foreach ($keys as $i => $k) {
$result[$k][] = $values[$i];
}
array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));
return $result;
}
function extract_data($str) {
return (is_array($str))
? array_map('extract_data', $str)
: ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches))
? $str
: array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}
print_r(extract_data(file_get_contents("http://www.google.com/")));
私はhttps://github.com/ivopetkov/html5-dom-document-phpで自由に利用できるHTML5DOMDocumentと呼ばれるライブラリを作成しました
クエリセレクターもサポートしているので、あなたの場合は非常に役立つと思います。ここにいくつかのサンプルコードがあります:
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
jQueryセレクターに慣れている場合は、ScarletsQuery for PHPを使用できます。
<pre><?php
include "ScarletsQuery.php";
// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);
// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];
// Get 'content' attribute value from meta tag
print_r($description->attr('content'));
$description = $dom->selector('#Content p');
// Get element array
print_r($description->view);
このライブラリは通常、オフラインHTMLの処理に1秒もかかりません。
また、タグ属性で無効なHTMLまたは欠落した引用を受け入れます。
XMLを解析するための最良の方法:
$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
$i++;
echo $title=$feedItem->title;
echo '<br>';
echo $link=$feedItem->link;
echo '<br>';
if($feedItem->description !='') {
$des=$feedItem->description;
} else {
$des='';
}
echo $des;
echo '<br>';
if($i>5) break;
}