这是我试图抓取的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]
- 哪里???是1-5之间的数字。
如果那是对的,那么我猜它回到了一个好的旧正则表达式(我没用过),不幸的是,这是我提出的最好的结果。尝试抓住它:
preg_match('/<h2>Description<\/h2>\s*<p>(.+)<\/p>/',$html,$rawdesc);
当然它不起作用......或者我不会辜负你的怜悯:)
答案 0 :(得分: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;
答案 1 :(得分:0)
此模式有效:
preg_match('~<h2>Description</h2>\s*<p>\K(?>[^<]++|<++(?!/p>))+~', $html, $rawdesc);
print_r($rawdesc);
如果您在?
+
,那么您也可以使用
答案 2 :(得分: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
合并它们。但也许我不明白你的问题。
答案 3 :(得分:0)
如果preg_match本身存在问题,您也可以尝试在模式中添加/ s开关,即preg_match('/<h2>Description<\/h2>\s*<p>(.+?)<\/p>/s',$html,$rawdesc);