PHP - 在Xpath查询中进一步挖掘

时间:2014-11-23 21:20:37

标签: php xpath

我一直在努力学习如何使用此视频中的Xpath类型的查询:https://www.youtube.com/watch?v=632ql93H90g

虽然我已经开始略微理解我想要更进一步的一切,然后尝试使用嵌套循环提取代码来提取嵌套元素然后对它们进行分类。我只是使用craigslist作为一个例子,因为他们在视频中启动了它并将其列在他们的“网站”网页下。

我必须重写这个,因为它之前有无限循环。现在,如果任何人知道更好的写作方式,我会很喜欢这些输入,但这就是我所拥有的。

我所要做的就是将结果变成以下格式......

国家/地区 - CityNameTEXT - CityNameHREF

当然cityNameHref =城市的链接。

现在我正好知道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 nodeValues作为实际城市名称的地方。但我没有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

1 个答案:

答案 0 :(得分: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>";
        }
    }
}

修改

这就是我如何做到的 首先,我使用firefox与firebugfirepath(我猜你可以找到其他网络浏览器的类似工具)。
这个工具让我可以尝试一些Xpath而无需编写PHP代码。

使用firebug,您可以看到DOM树,这对于了解您可以访问的内容非常有用,...然后尝试使用firepath的Xpath

首先,我选择了文档中的所有 H1 节点//h1,然后您需要为每个 H1 获取所有 H4 获取状态,但不幸的是 H4 节点不是 H1 节点的子节点,所以如果你想从 H1 <开始,你需要找到另一种方法来达到它/ strong>节点。

如果您查看 DOM树,您会看到div(包含 H4 节点)是 H1 的下一个兄弟之一节点,所以我们选择它following-sibling::div[1](这只是当前h1节点的div <div class="colmask">。)
我们想要所有 H4 节点//h4然后我们已经following-sibling::div[1]//h4

现在我们对每个 H4 <a href...>执行相同操作,因此我们选择所有 LI 中的所有 A 节点下一个兄弟 UL H4 following-sibling::ul[1]//li/a

的节点

我希望这是可以理解的(当然也很有用)并且对于错误感到抱歉,英语不是我的语言。