如何解析 HTML/XML 并從中提取信息?
注意:顧名思義,它對于簡單的任務(wù)很有用。它使用正則表達(dá)式而不是 HTML 解析器,因此對于更復(fù)雜的任務(wù)來說速度會慢得多。其大部分代碼庫是在 2008 年編寫的,此后僅進(jìn)行了少量改進(jìn)。它不遵循現(xiàn)代 PHP 編碼標(biāo)準(zhǔn),并且很難合并到現(xiàn)代 PSR 兼容項目中。
// 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);
我更喜歡使用原生 XML 擴(kuò)展之一,因?yàn)樗鼈兣cPHP 通常比所有第 3 方庫更快,并為我提供了對標(biāo)記所需的所有控制。
DOM 能夠解析和修改現(xiàn)實(shí)世界(損壞的)HTML,它可以執(zhí)行 XPath 查詢.它基于 libxml。
使用 DOM 需要一些時間才能提高工作效率,但在我看來,這段時間是值得的。由于 DOM 是一個與語言無關(guān)的接口,您會發(fā)現(xiàn)多種語言的實(shí)現(xiàn),因此如果您需要更改編程語言,那么您很可能已經(jīng)知道如何使用該語言的 DOM API。
如何使用 DOM 擴(kuò)展已在 StackOverflow 上廣泛介紹,所以如果當(dāng)您選擇使用它時,您可以確定您遇到的大多數(shù)問題都可以通過搜索/瀏覽 Stack Overflow 來解決。
XMLReader 與 DOM 一樣,基于 libxml。我不知道如何觸發(fā) HTML 解析器模塊,因此使用 XMLReader 解析損壞的 HTML 可能不如使用 DOM 強(qiáng)大,在 DOM 中您可以明確地告訴它使用 libxml 的 HTML 解析器模塊。
另一個答案中提供了基本用法示例。
XML 解析器庫也基于 libxml,并實(shí)現(xiàn)了 SAX 風(fēng)格的 XML 推送解析器。對于內(nèi)存管理來說,它可能是比 DOM 或 SimpleXML 更好的選擇,但比 XMLReader 實(shí)現(xiàn)的拉解析器更難使用。
當(dāng)您知道 HTML 是有效的 XHTML 時,SimpleXML 是一個選項。如果您需要解析損壞的 HTML,甚至不要考慮 SimpleXml,因?yàn)樗鼤枞?/p>
提供了基本使用示例,并且有PHP 手冊中有很多其他示例。
如果您更喜歡使用第 3 方庫,我建議使用實(shí)際使用 DOM/libxml 下面而不是字符串解析。
這被描述為“廢棄軟件和錯誤:使用時需要您自擔(dān)風(fēng)險”,但似乎維護(hù)程度最低。
基于 DOM/libxml 構(gòu)建的好處是,您可以立即獲得良好的性能,因?yàn)槟诒緳C(jī)擴(kuò)展。然而,并非所有第三方庫都走這條路。下面列出了其中一些
我一般不推薦這個解析器。代碼庫很糟糕,解析器本身相當(dāng)慢并且占用內(nèi)存。并非所有 jQuery 選擇器(例如 子選擇器)都是可行的。任何基于 libxml 的庫都應(yīng)該輕松超越這一點(diǎn)。
再說一遍,我不會推薦這個解析器。 CPU 使用率高時速度相當(dāng)慢。也沒有清除創(chuàng)建的 DOM 對象內(nèi)存的功能。這些問題在嵌套循環(huán)中尤其嚴(yán)重。該文檔本身不準(zhǔn)確且拼寫錯誤,自 2016 年 4 月 14 日以來沒有任何修復(fù)響應(yīng)。
您可以使用上述內(nèi)容來解析 HTML5,但由于 HTML5 允許的標(biāo)記,可能會出現(xiàn)一些奇怪的情況。因此,對于 HTML5,您可能需要考慮使用專用解析器。請注意,這些是用 PHP 編寫的,因此與使用較低級別語言編譯的擴(kuò)展相比,性能較慢且內(nèi)存使用量增加。
最后也是最不推薦,您可以使用正則表達(dá)式從 HTML 中提取數(shù)據(jù)一個>。一般來說,不鼓勵在 HTML 上使用正則表達(dá)式。
您在網(wǎng)絡(luò)上找到的大多數(shù)用于匹配標(biāo)記的代碼片段都很脆弱。在大多數(shù)情況下,它們僅適用于非常特定的 HTML 片段。微小的標(biāo)記更改(例如在某處添加空格,或者在標(biāo)記中添加或更改屬性)可能會導(dǎo)致正則表達(dá)式在編寫不正確時失敗。在 HTML 上使用 RegEx 之前,您應(yīng)該知道自己在做什么。
HTML 解析器已經(jīng)知道 HTML 的語法規(guī)則。必須為您編寫的每個新正則表達(dá)式教授正則表達(dá)式。正則表達(dá)式在某些情況下很好,但這實(shí)際上取決于您的用例。
您可以編寫更可靠的解析器,但是使用正則表達(dá)式編寫完整且可靠的自定義解析器當(dāng)上述庫已經(jīng)存在并且在這方面做得更好時,這是浪費(fèi)時間。
另請參閱克蘇魯方式解析 Html
如果你想花點(diǎn)錢,可以看看
我不隸屬于 PHP 架構(gòu)師或作者。