0

这是我要抓取的 HTML 片段:

    <div class="dot"><hr/></div>





    <h2>Description</h2>












        <p>This is the information I am trying to scrape</p>


</div>

我不认为我可以使用 XPath 来检索它的内容,<p>因为它没有 id 也没有类,并且取决于上面的其他信息,firebug 提供的 XPath 可以是/html/body/div[3]/div/div[???]/p[2]- where ??? 是 1-5 之间的数字。

如果这是正确的,那么我猜它又回到了一个很好的旧正则表达式(我没用),不幸的是,这是我想出的最好的尝试抓住它:

preg_match('/<h2>Description<\/h2>\s*<p>(.+)<\/p>/',$html,$rawdesc);

当然它不起作用....否则我不会把自己扔给你的怜悯:)

4

4 回答 4

2

Xpath 或类似的 DOM 解析库在解析 html 时总是比正则表达式更好。除非您正在查看一个极其简单的单一用例,否则真的没有例外。

如果您希望p直接在标记之后匹配元素h2,请使用如下所示的 xpath:

.//p[preceding-sibling::*[1][self::h2]]

我相信可以使用更简单的 xpath 查询,但这是我已经测试和验证的工作。

以下代码将为您提供所需的内容:

$dom = new DOMDocument();
$dom->loadHTML($yourHtmlString);
$xpath = new DOMXpath($dom);
$results = $xpath->query('.//p[preceding-sibling::*[1][self::h2]]');
$result = $results->item(0)->nodeValue;
于 2013-07-10T17:55:12.567 回答
0

这种模式有效:

preg_match('~<h2>Description</h2>\s*<p>\K(?>[^<]++|<++(?!/p>))+~', $html, $rawdesc);
print_r($rawdesc);

如果您?+

于 2013-07-09T22:23:45.587 回答
0

似乎您需要首先将其限制在$html包含描述的部分,例如

$start = strpos($html, '<h2>Description</h2>');
$end = strpos($html, '</div>', $start)
$html = substr($html, $start, $end-$start)

然后,您可以按照 PeeHaa 的建议进行操作并全部<p>...</p>使用preg_match_all. 然后用于implode合并它们。但也许我不明白你的问题。

于 2013-07-09T22:31:21.633 回答
0

如果 preg_match 本身是问题,您也可以尝试在模式中添加 /s 开关,即preg_match('/<h2>Description<\/h2>\s*<p>(.+?)<\/p>/s',$html,$rawdesc);

于 2013-07-09T23:38:07.603 回答