【问题标题】:Grab text content with xpath使用 xpath 抓取文本内容
【发布时间】:2013-11-14 13:28:26
【问题描述】:

我想从 advisor.travel 网站获取地点的名称和坐标,内容是 CC,所以我只需要前 10 页的名称和坐标...

到景点的链接是链接格式:http://en.advisor.travel/poi/1 所以'http://en.advisor.travel/poi/'.i 其中i 是景点的数量

我只想获得前 10 个吸引力,所以我在 1 和 10 之间,名称的 xpath 是

//h1 tag

坐标的xpath是:

//span[@class='latitude']
//span[@class='longitude']

我现在创建一个刮板,代码是:

<?php


for ($i=0; $i<=10; $i++)
  {
  $dom2 = new DOMDocument();
  @$dom2->loadHTMLFile('http://en.advisor.travel' . $i);
  $xpath2 = new DOMXPath($dom2);
  $data = array();
  $data[name] = $xpath2->query("//h1");
  $data[latitude] = $xpath2->query("//span[@class='latitude']");
  $data[longitude] = $xpath2->query("//span[@class='longitude']");

  } 
echo '<pre>' . print_r($data, true) . '</pre>';



?>

但是这个结果代码只给了我这个:

Array
(
    [name] => DOMNodeList Object
        (
            [length] => 0
        )

    [latitude] => DOMNodeList Object
        (
            [length] => 0
        )

    [longitude] => DOMNodeList Object
        (
            [length] => 0
        )

)       

那么我该如何解决呢?这里有什么问题?

【问题讨论】:

    标签: php html dom xpath for-loop


    【解决方案1】:

    您正在使用 (@) 运算符抑制错误,因此您没有注意到 URL 实际上不正确。

    调用应该是:

    @$dom2->loadHTMLFile('http://en.advisor.travel/poi/' . $i);
    

    下面还有以下内容:

    $data[name] = $xpath2->query("//h1");
    

    这行(以及下面的两行)有两处错误:

    • 您正在使用常量作为键。你应该用单引号括起来。
    • 即使上述错误得到纠正,您也只能获得for 循环的最后一次迭代的值。要将元素正确推送到 $data 数组中,您必须使用 $data['key'][] 语法。

    您将不得不访问该 XPath 节点的 textContent,而不是简单地查询 XPath。为此,您可以使用textContent()

    $data['name'][] = $xpath2->query("//h1")->item(0)->textContent;
    $data['latitude'][] = $xpath2->query("//span[@class='latitude']")
                                                        ->item(0)->textContent;
    $data['longitude'][] = $xpath2->query("//span[@class='longitude']")
                                                        ->item(0)->textContent;
    

    完整的代码应该是这样的:

    <?php
    
    for ($i=0; $i<=12; $i++)
    {
        $dom2 = new DOMDocument();
        @$dom2->loadHTMLFile('http://en.advisor.travel/poi/' . $i);
        $xpath2 = new DOMXPath($dom2);
        $data = array();
        $data['title'][] = $xpath2->query("//h1")->item(0)->textContent;
        $data['latitude'][] = $xpath2->query("//span[@class='latitude']")->item(0)->textContent;
        $data['longitude'][] = $xpath2->query("//span[@class='longitude']")->item(0)->textContent;
        echo "<hr/>";
    } 
    
    echo '<pre>' . print_r($data, true) . '</pre>';
    
    ?>
    

    从技术上讲,这应该可行,但由于要查询 12 个不同的 URL,我认为这不是一个好主意,因此不推荐。

    【讨论】:

    • 最好的方法是什么?
    • @drCode:没有更好的方法。屏幕抓取被认为是一个非常糟糕的主意。无论如何,如果你已经有了位置,你可以使用Google Maps API 来获取纬度和经度:)
    • 是的,但是我如何才能将抓取的请求一一发送到该站点...现在我同时发送所有 10 个请求...如何一一发送... etx .一个请求,暂停 5 秒,然后再次发送其他请求...
    • @drCode:您可以使用sleep() -- 即sleep(5) -- 您可能还想在脚本的最顶部设置set_time_limit(0) 以确保您不会到达最大执行时间限制。
    • @drCode:在for ($i=0; $i&lt;=12; $i++) {之后。
    猜你喜欢
    • 2018-01-02
    • 2020-12-29
    • 2014-09-23
    • 2011-10-13
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    相关资源
    最近更新 更多