開(kāi)發(fā)人員時(shí)不時(shí)地需要抓取網(wǎng)頁(yè)以從網(wǎng)站獲取一些信息。例如,假設(shè)您正在開(kāi)發(fā)一個(gè)個(gè)人項(xiàng)目,您必須從維基百科獲取有關(guān)不同國(guó)家首都的地理信息。手動(dòng)輸入會(huì)花費(fèi)很多時(shí)間。不過(guò),您可以借助 PHP 抓取維基百科頁(yè)面,非常快速地完成此操作。您還可以自動(dòng)解析 HTML 以獲取特定信息,而無(wú)需手動(dòng)瀏覽整個(gè)標(biāo)記。
在本教程中,我們將了解一種名為 DiDOM 的快速且易于使用的 HTML 解析器。我們將從安裝過(guò)程開(kāi)始,然后學(xué)習(xí)如何使用不同類型的選擇器(如標(biāo)簽、類等)從網(wǎng)頁(yè)上的不同元素中提取信息。
安裝與使用
您可以通過(guò)運(yùn)行以下命令輕松在項(xiàng)目目錄中安裝 DiDOM:
composer require imangazaliev/didom
登錄后復(fù)制
運(yùn)行上述命令后,您將能夠從字符串、本地文件或網(wǎng)頁(yè)加載 HTML。這是一個(gè)例子:
require_once('vendor/autoload.php');
use DiDom\Document;
$document = new Document($washington_dc_html_string);
$document = new Document('washington_dc.html', true);
$url = 'https://en.wikipedia.org/wiki/Washington,_D.C.';
$document = new Document($url, true);
登錄后復(fù)制
當(dāng)您決定從文檔中解析 HTML 時(shí),它可能已經(jīng)被加載并存儲(chǔ)在變量中。在這種情況下,您只需將該變量傳遞給 Document(),DiDOM 將準(zhǔn)備要解析的字符串。
如果必須從文件或 URL 加載 HTML,您可以將其作為第一個(gè)參數(shù)傳遞給 Document() 并將第二個(gè)參數(shù)設(shè)置為 true。
您還可以使用不帶任何參數(shù)的 new Document() 創(chuàng)建一個(gè)新的 Document 對(duì)象。在這種情況下,您可以調(diào)用方法 loadHtml() 從字符串加載 HTML,并調(diào)用 loadHtmlFile() 從文件或網(wǎng)頁(yè)加載 HTML。
查找 HTML 元素
從元素獲取 HTML 或文本之前要做的第一件事是找到元素本身。最簡(jiǎn)單的方法是使用 find() 方法并將所需元素的 CSS 選擇器作為第一個(gè)參數(shù)傳遞。
您還可以將元素的 XPath 作為 find() 方法的第一個(gè)參數(shù)傳遞。但是,這需要您傳遞 Query::TYPE_XPATH 作為第二個(gè)參數(shù)。
如果您只想使用 XPath 值來(lái)查找 HTML 元素,則可以簡(jiǎn)單地使用 xpath() 方法,而不是傳遞 Query::TYPE_XPATH每次作為 find() 的第二個(gè)參數(shù)。
如果 DiDOM 可以找到與傳遞的 CSS 選擇器或 XPATH 表達(dá)式匹配的元素,它將返回 DiDom\Element 實(shí)例的數(shù)組。如果沒(méi)有找到這樣的元素,它將返回一個(gè)空數(shù)組。
由于這些方法返回一個(gè)數(shù)組,因此您可以使用 find()[n-1] 直接訪問(wèn)第 n 個(gè)匹配元素。
一個(gè)例子
在下面的示例中,我們將從有關(guān)華盛頓特區(qū)的維基百科文章中的所有一級(jí)和二級(jí)標(biāo)題中獲取內(nèi)部 HTML
require_once('vendor/autoload.php');
use DiDom\Document;
$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);
$main_heading = $document->find('h1.firstHeading')[0];
echo $main_heading->html();
$sub_headings = $document->find('h2');
foreach($sub_headings as $sub_heading) {
if($sub_heading->text() !== 'See also') {
echo $sub_heading->html();
} else {
break;
}
}
登錄后復(fù)制
我們首先通過(guò)傳遞有關(guān)華盛頓特區(qū)的維基百科文章的 URL 來(lái)創(chuàng)建一個(gè)新的 Document 對(duì)象。之后,我們使用 find() 方法獲取主標(biāo)題元素并將其存儲(chǔ)在名為 $main_heading 的變量?jī)?nèi)。我們現(xiàn)在可以在此元素上調(diào)用不同的方法,例如 text()、innerHtml()、html() 等
對(duì)于主標(biāo)題,我們只需調(diào)用 html() 方法即可返回整個(gè)標(biāo)題元素的 HTML。同樣,我們可以使用 innerHtml() 方法獲取特定元素內(nèi)的 HTML。有時(shí),您會(huì)對(duì)元素的純文本內(nèi)容而不是其 HTML 更感興趣。在這種情況下,您只需使用 text() 方法即可完成。
二級(jí)標(biāo)題將我們的維基百科頁(yè)面劃分為定義明確的部分。但是,您可能希望刪除其中一些副標(biāo)題,例如“另請(qǐng)參閱”、“注釋”等。
一種方法是循環(huán)遍歷所有二級(jí)標(biāo)題并檢查 text() 方法返回的值。如果返回的標(biāo)題文本是“另請(qǐng)參閱”,我們將跳出循環(huán)。
使用 $document->find('h2')[3] 和 $document- 可以直接到達(dá)第四或第六級(jí)二級(jí)標(biāo)題>find('h2')[5] 分別。
上下遍歷 DOM
一旦您可以訪問(wèn)特定元素,該庫(kù)就可以讓您上下遍歷 DOM 樹(shù)以輕松訪問(wèn)其他元素。
您可以使用 parent() 方法轉(zhuǎn)到 HTML 元素的父元素。同樣,您可以使用 nextSibling() 和 previousSibling() 方法獲取元素的下一個(gè)或上一個(gè)同級(jí)元素。
還有很多方法可用于訪問(wèn) DOM 元素的子元素。例如,您可以使用 child(n) 方法獲取特定的子元素。同樣,您可以使用 firstChild() 和 lastChild() 方法訪問(wèn)特定元素的第一個(gè)或最后一個(gè)子元素。您可以使用 children() 方法循環(huán)遍歷特定 DOM 元素的所有子元素。
一旦到達(dá)特定元素,您將能夠使用 html()、innerHtml() 和text() 方法。
在下面的示例中,我們從二級(jí)標(biāo)題元素開(kāi)始,并繼續(xù)檢查下一個(gè)同級(jí)元素是否包含一些文本。一旦我們找到帶有一些文本的同級(jí)元素,我們就會(huì)將其輸出到瀏覽器。
require_once('vendor/autoload.php');
use DiDom\Document;
$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);
$sub_headings = $document->find('h2');
for($i = 1; $i < count($sub_headings); $i++) {
if($sub_headings[$i]->text() !== 'See also') {
$next_sibling = $sub_headings[$i]->nextSibling();
while(!$next_elem->html()) {
$next_sibling = $next_sibling->nextSibling();
}
echo $next_elem->html()."<br>";
} else {
break;
}
}
登錄后復(fù)制
您可以使用類似的技術(shù)循環(huán)遍歷所有同級(jí)元素,并且僅在文本包含特定字符串或同級(jí)元素是段落標(biāo)記等時(shí)輸出文本。一旦您了解了基礎(chǔ)知識(shí),找到正確的信息就是簡(jiǎn)單的。
操作元素屬性
在某些情況下,獲取或設(shè)置不同元素的屬性值的能力非常有用。例如,我們可以使用 $image_elem->attr( 'src').以類似的方式,您可以獲得文檔中所有 a 標(biāo)記的 href 屬性的值。
可以通過(guò)三種方法獲取 HTML 元素的給定屬性的值。您可以使用 getAttribute('attrName') 方法并將您感興趣的屬性名稱作為參數(shù)傳遞。您還可以使用 attr(‘attrName’) 方法,其工作方式與 getAttribute() 類似。最后,該庫(kù)還允許您使用 $elem->attrName 直接獲取屬性值。這意味著您可以使用 $imageElem->src 直接獲取圖像元素的 src 屬性值。
require_once('vendor/autoload.php');
use DiDom\Document;
$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);
$images = $document->find('img');
foreach($images as $image) {
echo $image->src."<br>";
}
登錄后復(fù)制
一旦您有權(quán)訪問(wèn)src屬性,您就可以編寫代碼來(lái)自動(dòng)下載所有圖像文件。這樣,您將能夠節(jié)省大量時(shí)間。
您還可以使用三種不同的技術(shù)來(lái)設(shè)置給定屬性的值。首先,您可以使用 setAttribute(‘attrName’, ‘attrValue’) 方法來(lái)設(shè)置屬性值。您還可以使用 attr(‘attrName’, ‘attrValue’) 方法來(lái)設(shè)置屬性值。最后,您可以使用 $Elem->attrName = 'attrValue' 設(shè)置給定元素的屬性值。
添加、刪除和替換元素
您還可以使用庫(kù)提供的不同方法對(duì)加載的 HTML 文檔進(jìn)行更改。例如,您可以使用 appendChild()、replace() 和 從 DOM 樹(shù)添加、替換或刪除元素">刪除() 方法。
該庫(kù)還允許您創(chuàng)建自己的 HTML 元素,以便將它們附加到原始 HTML 文檔中。您可以使用 new Element('tagName', 'tagContent') 創(chuàng)建新的 Element 對(duì)象。
請(qǐng)記住,如果您的程序在實(shí)例化之前不包含行 use DiDom\Element ,您將收到未捕獲錯(cuò)誤:未找到“Element”類錯(cuò)誤元素對(duì)象。
獲得該元素后,您可以使用 appendChild() 方法將其附加到 DOM 中的其他元素,也可以使用 replace( ) 方法使用新實(shí)例化的元素來(lái)替換文檔中某些舊的 HTML 元素。下面的例子應(yīng)該有助于進(jìn)一步闡明這個(gè)概念。
require_once('vendor/autoload.php');
use DiDom\Document;
use DiDom\Element;
$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);
// This will result in error.
echo $document->find('h2.test-heading')[0]->html()."\n";
$test_heading = new Element('h2', 'This is test heading.');
$test_heading->class = 'test-heading';
$document->find('h1')[0]->replace($test_heading);
echo $document->find('h2.test-heading')[0]->html()."\n";
登錄后復(fù)制
最初,我們的文檔中沒(méi)有 test-heading 類的 h2 元素。因此,如果我們嘗試訪問(wèn)這樣的元素,我們將不斷收到錯(cuò)誤。
驗(yàn)證不存在這樣的元素后,我們創(chuàng)建一個(gè)新的h2元素,并將其class屬性的值更改為test-heading >.
之后,我們將文檔中的第一個(gè) h1 元素替換為新創(chuàng)建的 h2 元素。再次在我們的文檔中使用 find() 方法查找?guī)в?test-heading 類的 h2 標(biāo)題,現(xiàn)在將返回一個(gè)元素。
最終想法
本教程介紹了 PHP DiDOM HTML 解析器的基礎(chǔ)知識(shí)。我們從安裝開(kāi)始,然后學(xué)習(xí)如何從字符串、文件或 URL 加載 HTML。之后,我們討論了如何根據(jù) CSS 選擇器或 XPath 查找特定元素。我們還學(xué)習(xí)了如何獲取元素的兄弟元素、父元素或子元素。其余部分介紹了如何操作特定元素的屬性或在 HTML 文檔中添加、刪除和替換元素。
如果您希望我在教程中澄清任何內(nèi)容,請(qǐng)隨時(shí)在評(píng)論中告訴我。
以上就是使用DiDOM解析HTML的PHP代碼的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注www.92cms.cn其它相關(guān)文章!






