【问题标题】:Using PHP and XPATH, how would you get the contents of the closest `h3`?使用 PHP 和 XPATH,您将如何获取最接近的 `h3` 的内容?
【发布时间】:2014-10-02 11:25:17
【问题描述】:
  • 使用 PHP 和 XPATH,您将如何正确获取最近的 h3 标记的文本,其中包含斯托克城与水晶宫比赛的日期? (例如 10 月 4 日星期六)
  • 本质上,我正在搜索比赛日期,我的输入是主队和客队
  • HTML sn-p 列表 4(其余 321 个)2014/15 赛季英超联赛足球赛程

    <div class="fixtures">
        <h3>Monday 29 September</h3>
        <dl class="matches">
            <dt class="match">
                <span class="match-time">20:00</span>
                <span class="home-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=110" alt="Stoke City">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/stoke-city.html">Stoke City</a>
                </span>
                <span>
                    <span>&nbsp;</span>
                    <span>vs</span>
                    <span>&nbsp;</span>
                </span>
                <span class="away-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=4" alt="Newcastle United">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/newcastle-united.html">Newcastle United</a>
                </span>
            </dt>
        </dl>
        <dl class="matches">
            <dt class="match">
                <span class="match-time">15:00</span>
                <span class="home-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=13" alt="Leicester City">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/leicester.html">Leicester City</a>
                </span>
                <span>
                    <span>&nbsp;</span>
                    <span>vs</span>
                    <span>&nbsp;</span>
                </span>
                <span class="away-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=90" alt="Burnley">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/burnley.html">Burnley</a>
                </span>
            </dt>
        </dl>              
        <h3>Saturday 4 October</h3>
        <dl class="matches">
            <dt class="match">
                <span class="match-time">15:00</span>
                <span class="home-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=14" alt="Liverpool">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/liverpool.html">Liverpool</a>
                </span>
                <span>
                    <span>&nbsp;</span>
                    <span>vs</span>
                    <span>&nbsp;</span>
                </span>
                <span class="away-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=35" alt="West Bromwich Albion">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/west-bromwich-albion.html">West Bromwich Albion</a>
                </span>
            </dt>
        </dl>            
        <dl class="matches">
            <dt class="match">
                <span class="match-time">15:00</span>
                <span class="home-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=110" alt="Stoke City">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/stoke-city.html">Stoke City</a>
                </span>
                <span>
                    <span>&nbsp;</span>
                    <span>vs</span>
                    <span>&nbsp;</span>
                </span>
                <span class="away-side">
                    <span>
                        <img src="http://omo.akamai.opta.net/image.php?&amp;sport=football&amp;entity=team&amp;description=badges&amp;dimensions=20&amp;id=31" alt="Crystal Palace">
                    </span>
                    <a href="http://www.dailymail.co.uk/sport/teampages/crystal-palace.html">Crystal Palace</a>
                </span>
            </dt>
        </dl>          
    </div>
    

【问题讨论】:

  • 这种结构总是一样的吗?
  • 是的 - 只是重复。例如div.fixtures 然后 h3 或 1 个或多个 dl.matches

标签: php html xpath domdocument


【解决方案1】:

你可以试试这个 XPath:

//h3[following-sibling::dl[1][.//span[contains(concat(' ', normalize-space(@class), ' '), ' home-side ') and span/img[@alt='Hull City']]]]

基本上,在 XPath 上方选择 &lt;h3&gt; 元素,其下一个兄弟 &lt;dl&gt; 元素包含一个 &lt;span class="home-side"&gt; 和另一个 &lt;span&gt;&lt;img alt="Hull City"&gt;(格式化版本):

//h3[
        following-sibling::dl[1][
                    .//span[
                        contains(concat(' ', normalize-space(@class), ' '), ' home-side ') 
                            and 
                        span/img[@alt='Hull City']
                    ]
        ]
    ]

更新:

以下是一个检查主队和客队的 XPath 示例:

//h3[
        following-sibling::dl[1][
                    .//span[
                        contains(concat(' ', normalize-space(@class), ' '), ' home-side ') 
                            and 
                        span/img[@alt='Hull City']
                    ]
                        and
                    .//span[
                        contains(concat(' ', normalize-space(@class), ' '), ' away-side ') 
                            and 
                        span/img[@alt='Crystal Palace']
                    ]
        ]

    ]

更新 2:

为了能够考虑多个&lt;dl&gt;s,我认为首先找到满足主客队标准的&lt;dl&gt; 会更容易,然后向后移动以从此类&lt;dl&gt; 中找到最接近的&lt;h3&gt; 元素:

//dl[
        .//span[
            contains(concat(' ', normalize-space(@class), ' '), ' home-side ') 
                and 
            span/img[@alt='Stoke City']
        ]
            and
        .//span[
            contains(concat(' ', normalize-space(@class), ' '), ' away-side ') 
                and 
            span/img[@alt='Crystal Palace']
        ]
    ]/preceding-sibling::h3[1]

【讨论】:

  • 您的回答实际上有助于解决我遇到的另一个问题,即扩展我的查询以定义客场:[.//span[contains(concat(' ', normalize-space(@class), ' '), ' away-side ') and span/img[@alt='West Bromwich Albion']]]。我如何将其包含在您建议的查询中?谢谢
  • 我没有提到的另一件事是&lt;h3&gt; 有时会引用多个&lt;dl&gt;,这样您就可以拥有:&lt;h3&gt; 然后&lt;dl&gt; 然后&lt;dl&gt; 然后@987654340 @ 然后&lt;dl&gt;。将更新我的问题
  • 如果有多个&lt;dl&gt;s,您希望发生什么?此答案中的 XPath 仅检查最接近的 &lt;dl&gt; ...
  • 它必须向上遍历,直到在&lt;dl&gt; 之前找到最接近的&lt;h3&gt; 作为兄弟 - 参见 HTML sn-p 示例。例如斯托克城对水晶宫应该在 10 月 4 日星期六举行
  • @u01jmg3 检查 更新 2 部分
【解决方案2】:

如果结构总是相同,您可以先将其指向具有该 alt 值的 img 标签,然后向后遍历。

例子:

$dom = new DOMDocument();
$dom->loadHTML($markup);
$xpath = new DOMXpath($dom);

$needle = 'Hull City';
$element = $xpath->query("//span/img[contains(@alt, '$needle')]");
if($element->length > 0) {
    $img = $element->item(0);
    $header = $xpath->query('ancestor::node()/preceding-sibling::h3[1]', $img);
    if($header->length > 0) {
        echo $header->item(0)->nodeValue; // Saturday 4 October
    }
}

Sample Output

【讨论】:

  • 我的建议是放弃[4]。它只是对文档结构产生了更高的依赖性,并且不需要。
  • @JLRishe 这是您的一个很好的建议,感谢您的洞察力
  • 效果很好,所以谢谢,但@har07 的建议看起来可以让我在同一个查询中定义离开的一面。
  • @Ghost:如果&lt;h3&gt; 用于多个匹配项,例如&lt;h3&gt; 然后&lt;dl&gt; 然后&lt;dl&gt;,会发生什么?例如如何在我的 sn-p 中获取莱斯特城主场比赛的比赛日期?
  • @u01jmg3 是的,它仍然说明了这一点,因为它找到了前面的&lt;h1&gt;,所以它向后看,然后[1] 得到第一个&lt;h3&gt;demo
猜你喜欢
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 2016-04-05
  • 2011-07-19
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
相关资源
最近更新 更多