使用正则表达式和simplehtmldom刮取数据

时间:2011-08-13 15:33:53

标签: php regex simple-html-dom

我正在尝试从此网站中删除一些数据:http://laperuanavegana.wordpress.com/。实际上我想要食谱和配料的标题。成分位于两个特定的关键字内。我试图使用正则表达式和simplehtmldom获取此数据。但它显示完整的HTML文本不仅仅是成分。这是我的代码:     

include_once('simple_html_dom.php');
$base_url = "http://laperuanavegana.wordpress.com/";

traverse($base_url);


function traverse($base_url)
{

    $html = file_get_html($base_url);
    $k1="Ingredientes";
    $k2="Preparación";
    preg_match_all("/$k1(.*)$k2/s",$html->innertext,$out);
    echo $out[0][0];
}

?>

此页面中有多种成分。我想要他们所有人。所以使用preg_match_all() 如果有人检测到此代码的错误,将会很有帮助。 提前谢谢。

2 个答案:

答案 0 :(得分:4)

当你已经在使用HTML解析器(即使是像SimpleHtmlDom这样糟糕的解析器)时,为什么还要尝试使用Regex来解决问题呢?这就像用手术刀打开病人,然后回到尖刀上进行实际手术。

因为我坚信没有人应该使用SimpleHtmlDom,因为它的代码库很差并且比基于libxml的解析器慢得多,这里是如何使用PHP's native DOM extensionXPath来实现的。 XPath实际上是X(HT)ML文档的Regex或SQL。了解它,因此您再也不必再使用Regex for HTML了。

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://laperuanavegana.wordpress.com/2011/06/11/ensalada-tibia-de-quinua-mango-y-tomate/');
libxml_clear_errors();

$recipe = array();
$xpath = new DOMXPath($dom);
$contentDiv = $dom->getElementById('content');
$recipe['title'] = $xpath->evaluate('string(div/h2/a)', $contentDiv);
foreach ($xpath->query('div/div/ul/li', $contentDiv) as $listNode) {
    $recipe['ingredients'][] = $listNode->nodeValue;
}
print_r($recipe);

这将输出:

Array
(
    [title] => Ensalada tibia de quinua, mango y tomate
    [ingredients] => Array
        (
            [0] => 250gr de quinua cocida tibia
            [1] => 1 mango grande
            [2] => 2 tomates
            [3] => Unas hojas de perejil
            [4] => Sal
            [5] => Aceite de oliva
            [6] => Vinagre balsámico
        )

)

请注意,我们不会解析http://laperuanavegana.wordpress.com/,而是解析实际的博文。只要博客所有者添加新帖子,主网址就会更改内容。

要从主页面获取所有食谱,您可以使用

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTMLFile('https://laperuanavegana.wordpress.com');
libxml_clear_errors();
$contentDiv = $dom->getElementById('content');
$xp = new DOMXPath($dom);
$recipes = array();
foreach ($xp->query('div/h2/a|div/div/ul/li', $contentDiv) as $node) {
    echo
        ($node->nodeName === 'a') ? "\n# " : '- ',
        $node->nodeValue,
        PHP_EOL;
}

这将输出

# Ensalada tibia de quinua, mango y tomate
- 250gr de quinua cocida tibia
- 1 mango grande
- 2 tomates
- Unas hojas de perejil
- Sal
- Aceite de oliva
- Vinagre balsámico

# Flan de lúcuma
- 1 lúcuma grandota o 3 pequeñas
- 1/2 litro de leche de soja evaporada
…

等等

另见

答案 1 :(得分:3)

您需要在那里添加问号。它使得模式不合适 - 否则它会占用页面上第一个$ k1到最后$ k2的所有内容。如果你添加问号,它将始终采用下一个$ k2。

preg_match_all("/$k1(.*?)$k2/s",$html->innertext,$out);