PHP 挖掘 XML 和 HTML 資料

來源:互聯網
上載者:User
資料採礦及其重要性

常用縮減詞

API: API CDATA: 字元資料 DOM: 文檔對象模式 FTP: 檔案傳輸通訊協定 HTML: 超文字標記語言 (HTML) HTTP: 超文字傳輸通訊協定 (HTTP) REST: 具象狀態傳輸 URL: 統一資源定位器 W3C: 全球資訊網聯盟 XML: 可延伸標記語言 (XML)

Wikipedia 對 “資料採礦” 的定義是 “資料採礦是採用統計學方法和人工智慧方法,結合資料庫管理,從大型資料集提模數式的過程”。這是一個非常深入的定義,可能超出了大多數人的典型用例。很少有人使用人工智慧;通常,資料採礦只是搜尋並彙集大型資料集,以尋找有用的資訊。

Internet 在飛速發展,並提供了海量資訊,因此,能夠收集大量資料並使資料變得有意義非常重要。收集個人無法讀完的大型資料集並將它們提煉為有用的資料是一個很重要的目標。這種類型的資料採礦是本文的焦點,本文將專門介紹如何收集和解析這種資料。

回頁首

資料採礦的實際應用

資料採礦有很多實際應用。您可能假設這樣一個情境:您想搜尋一個網站,尋找其中提供的資訊(比如電影或音樂會的出席記錄)。您可能需要檢索更嚴肅的資訊,比如投票者記錄,並獲得有用資料。或者,更常見的情況是,您可能需要檢查社交網路資料,試圖解析該資料,瞭解某種趨勢,比如您的公司被提及的頻率,以及這種提及是正面的還是負面的。

回頁首

挖掘網站之前的注意事項

在繼續介紹後面的內容之前,有一點需要說明:我們假定您將從另一個網站提取資料。如果您已經擁有要處理的資料,則又是完全不同的一種情況。當您從一個網站提取資料時,您需要確保遵守服務條款, 無論您是在做 Web 擦除(稍後將詳細介紹)還是在使用一個 API。如果您在做擦除,還需要注意遵守該網站的 robots.txt 檔案的規定,該檔案描述了允許訪問網站指令碼的哪些部分。最後,確保不會妨礙網站的頻寬。您編寫的指令碼不能按照指令碼能夠啟動並執行速度隨意訪問網站的資料。否則,這不僅可能會導致託管問題,還有可能面臨因為指令碼太具 “侵略性” 而遭到被禁止或阻塞的風險。

回頁首

理解 XML 資料結構

不管您採取何種方法提取資料,都有可能接收到 XML(或 HTML)格式的資料。當 XML 支援共用資料後,XML 就成為 Internet 的標準語言。在考慮提取資料的方法之前,重要的是要先研究 XML 結構和如何處理 XML 資料。

XML 文檔的基本結構非常直觀,特別是在您以前使用過 HTML 的情況下。XML 文檔中的所有資料都用兩種方法中的一種方法進行儲存。儲存資料的主要方法是將資料存放區在嵌套標記中。下面舉一個最簡單的例子,假設您擁有一個地址,則該資料可以按如下方法儲存在文檔中:

1234 Main Street, Baltimore, MD

您可以嵌套這些 XML 資料點,以建立多個地址的列表。您可以將所有這些地址放到另一個標記中,在本例中這個標記為locations(請參見 清單 1)。


清單 1. XML 中的多個地址

    1234 Main Street, Baltimore, MD    567 1st Street, San Jose, CA    901 Washington Ave, Chicago, IL

要進一步擴充這種方法,可以將這些地址分解為各個組成部分:街道、城市和州,這使得資料處理變得更簡單。這樣,產生的 XML 檔案就更典型,如 清單 2 所示。


清單 2. XML 中完全分解的地址

            1234 Main Street        Baltimore        MD                567 1st Street        San Jose        CA                901 Washington Ave        Chicago        IL    

前面提到過,儲存 XML 資料的方法有兩種,我們剛才看到了其中一種。另一種方法是通過屬性儲存區資料。可以為每個標記分配若干個屬性。儘管這種方法不那麼常用,但這可能是一種非常有用的工具。有時,它會提供額外的資訊,比如一個唯一 ID 或一個事件日期。更常見的情況是添加中繼資料; 在您的地址樣本中,可以使用一個 type 屬性來指出該地址是家庭地址還是工作地址,如 清單 3 所示。


清單 3. 添加到 XML 的標記

            1234 Main Street        Baltimore        MD                567 1st Street        San Jose        CA                901 Washington Ave        Chicago        IL    

注意,XML 文檔總是擁有一個父級根標記/節點,所有其他標記/節點都是該根標記/節點的子級標記/節點。XML 文檔的開頭部分還可以包含其他聲明和定義,以及其他複雜內容(比如 CDATA 塊)。強烈建議您參閱 參考資料 部分,以便進一步瞭解 XML。

回頁首

解析 PHP 中的 XML 資料

您已經瞭解了 XML 的外觀和結構,現在我們看看如何解析並以編程方式訪問 PHP 中的 XML 資料。有幾個針對 PHP 建立的庫允許進行 XML 解析,每個庫都有其優缺點。這些庫包括 DOM、XMLReader/Writer、XML Parser、SimpleXML 等。對於本文的目的,我們主要關注的是 SimpleXML,這是因為它是一個最常用的庫,同時也是我的最愛的庫之一。

SimpleXML,顧名思義,旨在提供一個非常簡單的介面來訪問 XML。它可以將 XML 文檔轉換為內部 PHP 對象格式。訪問資料點變得和訪問物件變數一樣簡單。要使用 SimpleXML 解析一個 XML 文檔,只需使用 simplexml_load_file() 函數(請參見 清單 4)。


清單 4. 使用 SimpleXML 解析文檔

 

就這麼簡單!但是請注意,多虧了 PHP 的檔案流整合,才可以在這裡插入一個檔案名稱或 URL,檔案流整合會自動取回它。如果 XML 已經載入記憶體,還可以使用 simplexml_load_string()。如果您在 清單 3 中的 XML 上運行這個代碼並使用 print_r() 來查看查看資料的大致結構,您將得到如 清單 5 所示的輸出。


清單 5. 已解析的 XML 的輸出

SimpleXMLElement Object (     [address] => Array         (             [0] => SimpleXMLElement Object                 (                     [@attributes] => Array                         (                             [type] => home                         )                     [street] => 1234 Main Street                     [city] => Baltimore                     [state] => MD                 )              [1] => SimpleXMLElement Object                 (                     [@attributes] => Array                         (                             [type] => work                         )                     [street] => 567 1st Street                     [city] => San Jose                     [state] => CA                 )              [2] => SimpleXMLElement Object                 (                     [@attributes] => Array                         (                             [type] => work                         )                      [street] => 901 Washington Ave                     [city] => Chicago                     [state] => IL                 )          ))

然後,您就可以使用標準的 PHP 對象訪問和方法訪問資料。例如,要回顯某人居住過的每個州,可以通過迭代地址來實現(請參見清單 6)。


清單 6. 迭代地址

address as $address) {    echo $address->state, "
\n";}?>

訪問屬性略有不同。與引用對象屬性不同的是,您可以將屬性作為數組值訪問。您可以更改上面的代碼範例來顯示 type 屬性,可以使用 清單 7 中所示代碼實現上述操作。


清單 7. 添加屬性

address as $address) {    echo $address->state, ': ', $address['type'], "
\n";}?>

儘管上述所有樣本都涉及迭代,但您也可以直接存取資料並使用您需要的特定資訊片段,比如通過下面的代碼提取第二個地址的街道地址:$xml->address[1]->street。

現在,您應該有一些基本工具來開始處理 XML 資料。有關的詳細資料,強烈建議您參閱 參考資料 中列出的 SimpleXML 文檔和其他連結。

回頁首

PHP 中的資料採礦:可能的方法

如前所述,可以用多種方法訪問資料,其中兩種主要方法是 Web 擦除和 API 使用。

Web 擦除

Web 擦除(scraping)是以編程方式下載所有 Web 頁面並從中提取資料的操作。有很多圖書專門討論了這個主題(請參閱 參考資料)。我只簡單列舉進行 Web 擦除所需的一些工具。首先,PHP 使得將一個 Web 頁讀入為一個字串變得非常簡單。有許多方法可以完成這個任務,包括通過某個 URL 使用 file_get_contents(),但在這裡,您希望能以一種有意義的方式來解析 HTML。

因為 HTML 實質上是一種基於 XML 的語言,所以將 HTML 轉換為一種 SimpleXML 結構很有用。但是不能只使用simplexml_load_file() 載入 HTML 頁面,因為即使是有效 HTML,它仍然不是 XML。一種好辦法是使用 DOM 擴充,將 HTML 頁面作為 DOM 文檔載入,然後將其轉換為 SimpleXML,如 清單 8 所示。


清單 8. 使用 DOM 方法來擷取 Web 頁面的 SimpleXML 版本

loadHTMLFile('http://example.com/');$xml = simplexml_import_dom($dom);?>

現在,您可以像對其他 XML 文檔一樣遍曆 HTML 頁面。因此,您現在可以使用 $xml->head->title 來訪問頁面標題,或者使用 $xml->body->div[0]->div[0]->div[0]->h4[0] 這樣的引用來深入頁面。

但是,正如您從上一個樣本中可以預料到的那樣,試圖從一個 HTML 頁面中尋找資料有時可能非常不便,這是因為 HTML 頁面通常不像 XML 檔案那樣有良好的結構。上面那行代碼尋找三個嵌套的 div 中的第一個 h4;在每種情況下,它都會尋找每個父 div 中的第一個 div。

幸運的是,如果您只想尋找頁面上的第一個 h4,或者其他 “直接資料”,那麼 XPath 是一種更簡單的實現方法。XPath 是一個非常強大的工具,可以將它作為整個文章系列的主題(請參閱 參考資料 中列示的部分文章)。簡言之,可以使用 '/' 來描述層級關係;因此,可以將前面的引用重寫為下面的 XPath 搜尋(請參見 清單 9)。


清單 9. 直接使用 XPath

xpath('/html/body/div/div/div/h4');?>

或者,您可以只使用 '//' 選項和 XPath,這將搜尋所有文檔,尋找您要尋找的標記。因此,您可以找到所有 h4,產生一個數組,然後使用下面的 XPath 訪問第一個 h4:
'//h4'

遍曆 HTML 分層結構

討論上述轉換和 XPath 的主要原因是,進行 Web 擦除的常見必要任務之一就是自動尋找 Web 頁面上的其他連結並追索它們,這允許您 “遍曆” 網站,找到盡量多的資訊。

如果使用 XPath,這個任務將非常麻煩。清單 10 提供了一個由所有帶有 “href” 屬性的 連結組成的數組,並允許您處理它們。


清單 10. 結合使用多種技術尋找頁面上的所有連結

loadHTMLFile('http://example.com/');$xml = simplexml_import_dom($dom);$links = $xml->xpath('//a[@href]');foreach ($links as $l) {    echo $l['href'], "
\n";}?>

現在,上面的代碼找到了所有 連結,但如果您開啟您發現的每個可能連結,您就開始快速 “爬行” 整個 Web。因此,最好增強您的代碼,確保只訪問兩類連結:一類是有效 HTML 連結(不是 FTP 或 JavaScript);一類是只返回(通過完整或相對域連結)同一個網站的連結。

一種更簡單的方法是使用 PHP 的內建 parse_url() 函數在這些連結上進行迭代,該函數為您處理大量資格審查,如 清單 11 所示。


清單 11. 一個更健壯的網站遍曆程式

loadHTMLFile("http://{$host}/");$xml = simplexml_import_dom($dom);$links = $xml->xpath('//a[@href]');foreach ($links as $l) {    $p = parse_url($l['href']);    if (empty($p['scheme']) || in_array($p['scheme'], array('http', 'https'))) {        if (empty($p['host']) || ($host == $p['host'])) {            echo $l['href'], "
\n"; // Handle URL iteration here } }}?>

關於 HTML 解析的最後一點說明是,對於所有 XML 類語言的一個統一介面,您複習了如何只使用 DOM 擴充將 HTML 轉換回 SimpleXML。注意,DOM 庫本身非常強大,可以直接使用。如果您非常熟悉 JavaScript 和使用 getElementsByTagName 之類的工具來遍曆 DOM 文檔樹,那麼您完全可以只使用 DOM 庫,不使用 SimpleXML。

您目前應該已經擁有了從 Web 頁面上擦除資料所需的工具。一旦您熟悉了本文前面詳細介紹的技術,就可以從 Web 頁面上讀取任何資訊,而不僅限於可以關注的連結。我們希望您不必執行這個任務,因為已經存在 API 或其他資料來源。

使用 XML API 和資料

此時,您已經掌握了一些基本技能,能夠訪問和使用 Internet 上的主要 XML 資料 API。它們通常基於 REST,因此只需一個簡單的 HTTP 訪問就可以檢索資料,並使用前面介紹的結束來解析資料。

每個 API 在這方面的表現都是不同的。我們無法一一介紹如何訪問每個 API,因此,我們只簡要介紹一些基本的 XML API 樣本。一個最常見且已經採用 XML 格式的資料來源就是 RSS feed。RSS 代表 Really Simple Syndication,通常是一種標準化的格式,用於共用頻繁更新的資料,比如部落格文章、新聞標題或播客。要詳細瞭解 RSS 格式,請參見 參考資料。注意,RSS 是一個 XML 檔案,有一個名為 父標記,其中有若干 標記,每個標記都提供一組資料點。

下面舉例說明。假設我們使用 SimpleXML 來讀取紐約時報標題的 RSS feed(參見 參考資料 擷取到該 RSS feed 的連結)並格式化一欄位標題,那些標題都將連結到相應的本文(請參見 清單 12)。


清單 12. 讀取紐約時報的 RSS feed

     
    channel->item as $item) { echo "
  • link}\">{$item->title}
  • ";}?>

圖 1 顯示了來自紐約時報摘要的輸出。


來自紐約時報摘要的輸出

現在,我們來探索一個功能更全的基於 REST 的 API。Flickr API 是一個好的起點,因為它提供大量資料,但不需要身分識別驗證。許多 API 都需要身分識別驗證(使用 Oauth 或其他機制),以代表一個 Web 使用者進行操作。這個步驟可應用於整個 API,或者只應用於部分 API。參閱每個 API 文檔,瞭解如何進行身分識別驗證。

要瞭解如何對一個未經身分識別驗證的請求使用 Flickr API,您可以使用它的搜尋 API。作為一個樣本,我們搜尋 Flickr 的所有公用十字弓照片。儘管不必進行身分識別驗證,但與許多 API 一樣,仍然需要產生一個 API 密匙,以便在訪問資料時使用。請直接參閱 Flickr 的 API 文檔,瞭解如何完成這個任務。擁有一個 API 密匙後,就可以使用 Flickr API 的搜尋功能進行探索,如 清單 13 所示。


清單 13. 使用 Flickr API 搜尋 “crossbow”

 'flickr.photos.search',    'api_key' => $key,    'text' => 'crossbow', // Our search term    'media' => 'photos',    'per_page' => 20 // We only want 20 results);// Now make the request to Flickr:$xml = simplexml_load_file($apiurl . http_build_query($params));// From this, iterate over the list of photos & request more info:foreach ($xml->photos->photo as $photo) {    // Build a new request with this photo's ID    $params = array(        'method' => 'flickr.photos.getInfo',        'api_key' => $key,        'photo_id' => (string)$photo['id']    );    $info = simplexml_load_file($apiurl . http_build_query($params));        // Now $info holds a vast amount of data about the image including    //  owner, GPS, dates, description, tags, etc ... all to be used.    // Let's also request "sizes" to get all of the image URLs:    $params = array(        'method' => 'flickr.photos.getSizes',        'api_key' => $key,        'photo_id' => (string)$photo['id']    );    $sizes = simplexml_load_file($apiurl . http_build_query($params));    $small = $sizes->xpath("//size[@label='Small']");        // For now, just going to create a simple display of the image,    //  linked back to Flickr, with title, GPS info, and more shown:    echo <<urls->url[0]}">        
     
  • Title: {$info->photo->title}
  • User: {$info->photo->owner['realname']}
  • Date Taken: {$info->photo->dates['taken']}
  • Location: {$info->photo->location->locality}, {$info->photo->location->county}, {$info->photo->location->region}, {$info->photo->location->country}
EOHTML;}?>

圖 2 顯示了這個 Flickr 程式的輸出。您的十字弓搜尋結果包括一些照片和每張照片的相關資訊(標題、使用者、位置和攝影日期)。


圖 2. 來自清單 13 的 Flickr 程式的樣本輸出

您已經看到,這樣的 API 是多麼強大,以及如何在同一個 API 中結合各種調用來擷取所需的資料。通過這些基本技術,您可以挖掘任何網站和資訊源的資料。

考慮一下,如何通過一個 API 或 Web 擦除擷取對資料的編程訪問。然後使用所展示的方法來訪問并迭代所有目標資料。

回頁首

儲存和報告提取的資料

最後,儲存和報告資料在很多方面都是最容易的部分,可能也是最有意思的部分。當您決定如何根據您的實際情況處理這個方面時,您可以任意發揮您的想象力。

通常,獲得您收集的所有資料並將它們儲存到某個資料庫中。然後,設計您的資料結構,使其與您計劃將來訪問資料的方式相符。此時,盡量多儲存一些資訊,將來有可能會用到它們。儘管總是可以刪除資料,但一旦資料太多,檢索額外的資訊可能是一個痛苦的過程。但最好還是在剛開始就多儲存一些資料,畢竟,您永遠也不會知道哪些資料可能會派上用場。

將資料存放區到資料庫或類似的資料存放區器中之後,就可以建立報告了。建立報告可能很簡單,只需針對資料庫運行幾個基本的 SQL 查詢,查看某個資料出現的次數即可;或者,報告建立也可能是非常複雜的 Web 使用者介面,旨在允許使用者深入資料並探索資料之間的關係。

當您辛辛苦苦將所有資料分門別類後,便可以想象一些顯示資料的創新方法。

回頁首

結束語

通過本文,您瞭解了 XML 文檔的基本結構,以及使用 SimpleXML 來解析 PHP 中的 XML 資料的一種簡單方法。您還增加了以類似方式處理 HTML 的能力,並初步瞭解了如何遍曆一個網站,擷取沒有以 XML 格式提供的資料。通過這些工具,結合本文提供的一些樣本,現在您已經擁有了良好的知識基礎,可以開始對某個網站進行資料採礦了。關於這個主題還有許多知識需要學習,無法在一篇文章中對它們進行一一介紹。關於增加您的資料採礦知識的其他方法,請參閱 參考資料。

回頁首

下載

描述 名字 大小 下載方法
原始碼 datamining_source.zip 10KB HTTP

關於下載方法的資訊

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.