【问题标题】:PHP and DOM to extract these specific data of a web pagePHP 和 DOM 提取网页的这些特定数据
【发布时间】:2012-07-24 00:36:59
【问题描述】:

使用 PHP 和 DOM 如何从以下代码(网页的一部分)中获取 PLACE、ADDRESS、LOCALITY、REGION、POSTAL CODE 和 COUNTRY。

从现在开始我已经开发了一部分代码来获取其他内容。这是目前为止的代码。

$dochtml = new DOMDocument();
$dochtml->loadHTMLfile('');
$xpath = new DOMXpath($dochtml);

$descr = $xpath->query('//div[@class="description"]')->item(0);
    print_r($descr->nodeValue);

$abbr  = $dochtml->getElementsByTagName("abbr")->item(0);
    $title = $abbr->getAttribute("title");
    echo $title;

这是剩下的代码。

<div class="vcard location p">
    <div class="fn org">
        <a href="link here">PLACE</a>
    </div>
    <div class="adr">
        <div class="street-address">ADDRESS<br></div>
        <div>
            <span class="locality">LOCALITY</span>,
            <span class="region">REGION</span>
            <span class="postal-code">POSTAL CODE</span>,
            <span class="country-name">COUNTRY</span>
        </div>
    </div>
</div>

更新

我对以下内容有一个小问题,在页面中有很多 &lt;abbr&gt; 标签,但是我想要的两个标签类 dtstartdtend 如下是唯一在 @987654326 内的标签@。不幸的是,并非所有人都有第二个带有class=dtendabbr 标签,因此它从“相关事件”中获得第一个标签。所以我的问题是我如何将它限制在这个特定的 id 上?

<div id="eventDetailInfo">
        <div class="p">
         <div><abbr class="dtstart" title="2012-07-16T21:00:00">Monday, July 16th, 2012</abbr></div>    
         <div><abbr class="dtend" title="2012-08-16T21:00:00">Monday, August 16th, 2012</abbr></div>    
        </div>
</div>

【问题讨论】:

    标签: php dom web-scraping


    【解决方案1】:

    通过阅读DOMXPath documentation,我建议的解决方案概述如下。

    按类获取元素

    $nodes = $xpath->query('//div[contains(@class, "street-address")]');
    

    按 ID 获取元素

    $node = $xpath->query('//div[@id="someid"]');
    

    解决方案

    要提取您的值,您可以使用 (working example):

    <?php
    $html = '<div class="vcard location p">
        <div class="fn org">
            <a href="link here">PLACE</a>
        </div>
        <div class="adr">
            <div class="street-address">ADDRESS<br></div>
            <div>
                <span class="locality">LOCALITY</span>,
                <span class="region">REGION</span>
                <span class="postal-code">POSTAL CODE</span>,
                <span class="country-name">COUNTRY</span>
            </div>
        </div>
        <div id="eventDetailInfo">
            <div class="p">
             <div><abbr class="dtstart" title="2012-07-16T21:00:00">Monday, July 16th, 2012</abbr></div>    
             <div><abbr class="dtend" title="2012-08-16T21:00:00">Monday, August 16th, 2012</abbr></div>    
            </div>
        </div>
    </div>';
    
    $document = new DOMDocument();
    $document->loadHTML($html);
    $xPath = new DOMXpath($document);
    
    function extractNodeValue($query, $xPath, $attribute = null) {
        $node = $xPath->query("//{$query}")->item(0);
        if (!$node) {
            return null;
        }
        return $attribute ? $node->getAttribute($attribute) : $node->nodeValue;
    }
    
    $place = extractNodeValue('div[contains(@class, "fn")]/a', $xPath);
    $address = extractNodeValue('div[contains(@class, "street-address")]',$xPath);
    $locality = extractNodeValue('span[contains(@class, "locality")]',$xPath);
    $region = extractNodeValue('span[contains(@class, "region")]', $xPath);
    $postalCode = extractNodeValue('span[contains(@class, "postal-code")]', $xPath);
    $countryName = extractNodeValue('span[contains(@class, "country-name")]', $xPath);
    $start = extractNodeValue('div[@id="eventDetailInfo"]/div/div/abbr[contains(@class, "dtstart")]', $xPath, 'title');
    $end = extractNodeValue('div[@id="eventDetailInfo"]/div/div/abbr[contains(@class, "dtend")]', $xPath, 'title');
    
    var_dump($place, $address, $locality, $region, $postalCode, $countryName, $start, $end);
    

    输出:

    string(5) "PLACE" string(7) "ADDRESS" string(8) "LOCALITY" string(6) "REGION" string(11) "POSTAL CODE" string(7) "COUNTRY" string(19) "2012-07-16T21:00:00" string(19) "2012-08-16T21:00:00"
    

    【讨论】:

    • $place 周围有一些空间,因为您在里面有 &lt;a&gt; 标记,而您没有选择它。
    • 感谢您的出色回答。请看一下我的编辑,我已经发布了关于如何限制特定 id 的结果的另一件事。
    • @Kaoukkos 不完全确定您的意思,但请查看我最近的编辑
    • 再次感谢!我不是很清楚,但我需要使用2012-07-16T21:00:00 而不是Monday, August 16th, 2012
    • @Kaoukkos 更新了extractNodeValue 函数以允许可选地返回属性。
    【解决方案2】:

    您的代码几乎完成了:

    <?php
    
    $dochtml = new DOMDocument();
    $dochtml->loadHTML('<div class="vcard location p">
        <div class="fn org">
            <a href="link here">PLACE</a>
        </div>
        <div class="adr">
            <div class="street-address">ADDRESS<br></div>
            <div>
                <span class="locality">LOCALITY</span>,
                <span class="region">REGION</span>
                <span class="postal-code">POSTAL CODE</span>,
                <span class="country-name">COUNTRY</span>
            </div>
        </div>
    </div>');
    
    $xpath = new DOMXpath($dochtml);
    
    $place       = $xpath->query('//div[@class="fn org"]/a')->item(0)->nodeValue;
    $address     = $xpath->query('//div[@class="street-address"]')->item(0)->nodeValue;
    $locality    = $xpath->query('//span[@class="locality"]')->item(0)->nodeValue;
    $region      = $xpath->query('//span[@class="region"]')->item(0)->nodeValue;
    $postalCode  = $xpath->query('//span[@class="postal-code"]')->item(0)->nodeValue;
    $countryName = $xpath->query('//span[@class="country-name"]')->item(0)->nodeValue;
    

    直播代码available here.

    【讨论】:

    • 在尝试访问nodeValue之前应该检查节点是否存在,否则风险:E_NOTICE Notice: Trying to get property of non-object in __FILE__ on line __LINE__
    【解决方案3】:

    如果您知道 CSS 选择器,请使用 PHPQuery 或类似的库。

    【讨论】:

    • 他和 DOMXPath 差不多了
    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2012-07-19
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    相关资源
    最近更新 更多