2014-11-23 55 views
0

我一直在努力學習如何使用XPath類型querys從這段視頻越往下:https://www.youtube.com/watch?v=632ql93H90gPHP - 挖一個Xpath查詢

雖然我已經開始稍稍明白了一切,我想採取這一點,並嘗試使用嵌套循環提取代碼來提取嵌套元素,然後對它們進行分類。我只是使用craigslist作爲例子,因爲他們在視頻中啓動它,並將其列在其「網站」網頁下。

我不得不重寫這個,因爲之前它有一個無限循環。現在,如果任何人知道寫這個更好的方式,我會喜歡輸入,但這是我的。

所有我一直在努力做的就是我的結果分爲以下格式....

國家 - 國家 - CityNameTEXT - CityNameHREF

當然cityNameHref = thelink城市的

現在,現在我只是在用它的print_r具有內在的結果我市實際的上市,因爲從Craigslist的格式是..

<h1>CountryName</h1> 
<div class="colmask"> 
<div> 
    <h4>StateName</h4> 
    <ul> 
    <li> 
    <a href="CityNameHREF">CityName</a> 
    </li> 
    <li> 
    <a href="CityNameHREF">CityName</a> 
    </li> 
     <li> 
    <a href="CityNameHREF">CityName</a> 
    </li> 
    <li> 
    <a href="CityNameHREF">CityName</a> 
    </li> 
    </ul> 
</div> 
</div> 

正如你可以看到它的嵌套非常複雜的內部。我一直試圖堅持12個小時,試圖讓這個工作。這是我得到的最接近顯示UL節點值的實際城市名稱。但我沒有CLUE如何讓這些城市以上面列出的格式正確顯示。

現在到我的代碼...

$url = 'http://www.craigslist.org/about/sites'; 
$output = file_get_contents($url); 
$doc = new DOMDocument(); 

    libxml_use_internal_errors(true); //Supress Warnings for HTML5 conversion issue 
    $doc->loadHTML($output); 
    libxml_use_internal_errors(false); //Start Showing Errors 

    $xpath = new DOMXpath($doc); 


foreach ($xpath->query('//h1') as $e) 
    { 
      $country = $e->nodeValue; 
      $list = array(); 


      foreach ($xpath->query('//div[@class="colmask"]/div', $e) as $li) 
      { 

       $state = $li->nodeValue;  
        echo "<pre>"; 


        $result = $xpath->query('//div[@class="colmask"]/div/ul', $e); 


        for ($i = 0; $i <= 10; $i++) //10 instead so it doesn't lag out 
        { 


        print_r($result->item($i)); //Displays the UL nodeValue 
        } 


      } 
    } 

Heres my example

+0

刪除我的評論爲@Duccydake使我更有意義;) – Wrikken 2014-11-23 22:18:28

回答

2

試試這個:

$url = 'http://www.craigslist.org/about/sites'; 
$output = file_get_contents($url); 
$doc = new DOMDocument(); 

libxml_use_internal_errors(true); //Supress Warnings for HTML5 conversion issue 
$doc->loadHTML($output); 
libxml_use_internal_errors(false); //Start Showing Errors 

$xpath = new DOMXpath($doc); 

foreach ($xpath->query('//h1') as $e) { 
    $country = trim($e->textContent); 

    foreach ($xpath->query('following-sibling::div[1]//h4', $e) as $h4) { 
     $state = trim($h4->textContent); 

     foreach ($xpath->query('following-sibling::ul[1]//li/a', $h4) as $a) { 
       $town = $a->textContent; 
       $attributeNodeMap = $a->attributes; 
       $nodeAttribute = $attributeNodeMap->getNamedItem("href"); 
       $href = trim($nodeAttribute->nodeValue); 

       echo "$country - $state - $town - $href<br>"; 
     } 
    } 
} 

編輯

所以這就是我如何做的。
首先,我用firebugfirepath(我猜你可以找到類似的工具用於其他網絡瀏覽器)的Firefox。
這個工具讓我在不寫PHP代碼的情況下嘗試一些Xpath。

Firebug的,你可以看到DOM樹是真正有用知道你能達到什麼......然後嘗試XPath和firepath

要開始我選擇了所有H1節點//h1文檔中和那麼你需要得到所有H4每個H1拿到狀態,但遺憾的是H4節點不是H1節點的孩子,所以你需要找到另一種方式來實現它,如果你想從啓動H1節點。

如果你看一下DOM樹你會看到一個div(包含H4節點)是H1節點的下一個兄弟之一,所以我們選擇它following-sibling::div[1](這是在div <div class="colmask">僅當前的h1節點)。
我們希望所有H4節點//h4然後我們有following-sibling::div[1]//h4

現在我們每個H4做了<a href...>同樣的事情,所以我們選擇所有所有節點A節點,其在接下來的兄弟UL的H4following-sibling::ul[1]//li/a

我希望這是可以理解的(當然是有用的)和對錯誤抱歉,英語不是我的語言。

+0

OMG非常感謝duffydake。我之前曾嘗試過使用以下兄弟姐妹,但遇到問題。我原本列在http://stackoverflow.com/questions/27086891/php-issues-with-infinite-looping因爲它保持循環通過城市。缺失的部分ul [1]部分是什麼。我甚至把它插入原來的帖子,現在它的作品。你能解釋一下那部分嗎?我知道這是想要得到第一個,但爲什麼它需要?您可以在consule中使用$ x(「」)在Google中執行X路徑查詢,但不知道如何在其中使用followibling。 – eqiz 2014-11-23 23:06:40

+0

是''[1]'只用於選擇第一個,否則你會選擇所有其他的,我不知道爲什麼對我來說它不應該。 – Duffydake 2014-11-23 23:13:59