【问题标题】:Preg_match_all not working on yahoo resultsPreg_match_all 不适用于雅虎结果
【发布时间】:2012-10-17 08:32:01
【问题描述】:

好的,所以 preg_match_all 对 Yahoo 不起作用。

我正在尝试使用 cURL curl_multi_getcontent 方法预匹配我从 Yahoo 获得的所有结果。

我已成功获取该站点等,但是当我尝试获取链接的结果时,它不会匹配任何内容。当我在 Notepad++ 中使用正则表达式时,它成功但在 PHP 中显然没有。

我目前正在使用:

preg_match_all(
    '#<span class="url" id="(.*?)">(.+?)</span>#si', $urlContents[2], $yahoo
);

例如检查[http://se.search.yahoo.com/search?p=random&amp;toggle=1&amp;cop=mss&amp;ei=UTF-8&amp;fr=yfp-t][1] 的HTML,您会看到所有链接都以&lt;span class="url" id="something random"&gt; 开头并以&lt;/span&gt; 结尾。

有人可以帮助我如何检索这些信息吗? 我只需要每个结果的实际链接地址。

整个 PHP 脚本

public function multiSearch($question)
{
    $sites['google'] = "http://www.google.com/search?q={$question}&gl=sv";
    $sites['bing'] = "http://www.bing.com/search?q={$question}";
    $sites['yahoo'] = "http://se.search.yahoo.com/search?p={$question}";

    $urlHandler = array();

    foreach($sites as $site)
    {
        $handler = curl_init();
        curl_setopt($handler, CURLOPT_URL, $site);
        curl_setopt($handler, CURLOPT_HEADER, 0);
        curl_setopt($handler, CURLOPT_RETURNTRANSFER, 1);

        array_push($urlHandler, $handler);
    }

    $multiHandler = curl_multi_init();
    foreach($urlHandler as $key => $url)
    {
        curl_multi_add_handle($multiHandler, $url);
    }

    $running = null;
    do
    {
        curl_multi_exec($multiHandler, $running);
    }
    while($running > 0);

    $urlContents = array();
    foreach($urlHandler as $key => $url)
    {
        $urlContents[$key] = curl_multi_getcontent($url);
    }

    foreach($urlHandler as $key => $url)
    {
        curl_multi_remove_handle($multiHandler, $url);
    }

    foreach($urlContents as $urlContent)
    {
        preg_match_all('/<li class="g">(.*?)<\/li>/si', $urlContent, $matches);
        //$this->view_data['results'][] = "Random";
    }
    preg_match_all('#<cite>(.+?)</cite>#si', $urlContents[1], $googleLinks);
    preg_match_all('#<span class="url" id="(.*)">(.+?)</span>#si', $urlContents[2], $yahoo);
    var_dump($yahoo);
    die();
    $findHtml = array('/<cite>/', '/<\/cite>/', '/<b>/', '/<\/b>/', '/ /', '/"/', '/<strong>/', '/<\/strong>/');
    $removeHtml = array('', '', '', '', '', '', '', '');
    foreach($googleLinks as $links => $val)
    {
        foreach($val as $link)
            $this->view_data['results'][] = preg_replace($findHtml, $removeHtml, $link);
        break;
    }
}

【问题讨论】:

  • 最好先查看您收到的 HTML,在纯 HTML 中没有&lt;span class="url"。它不是preg_match,而是你寻找存在的东西。
  • @hakre 我已经为 Yahoo 打印了好几次内容,如果
  • 嗯,很有趣,因为我刚刚查看了您提供的链接的来源,但找不到 &lt;span class="url"(标记名和属性名之间的一个空格)文字字符串。我只在执行 javascript 后在 DOM 中找到它。 Curl 不执行 javascript。
  • @hakre 这正是我从se.search.yahoo.com/…复制的内容www.random.org
  • 对我来说,在源代码中它看起来像&lt;span class=url&gt;,即属性值周围没有双引号。编辑:i.imgur.com/qzyBd.png - Jack 建议的 HTML 解析器的好处是它可以为您标准化结构,因此您可以更轻松地访问您要查找的内容。

标签: php regex preg-match-all


【解决方案1】:

首先,您不应该使用正则表达式来处理 HTML。有相当不错的 DOM 解析器可用于 PHP。例如:

$d = new DOMDocument;
$d->loadHTML($s);
$x = new DOMXPath($d);
foreach ($x->query('//span[@class="url"]') as $node) {
        // process each node the way you wish
        // print the id for instance
        echo $node->getAttribute('id'), PHP_EOL;
}

除此之外,表达式应该可以工作,除了id="(.*)" 是贪婪的;可以通过以下方式修复:

#<span class="url" id="(.*?)">(.+?)</span>#si

id="..."&gt; 之后可能还有更多文字;这将使表达式变为:

#<span class="url" id="(.*?)"[^>]*>(.+?)</span>#si

【讨论】:

  • 你好@Jack。正如我之前提到的。即使我使用它也不起作用。它不会匹配任何东西。
  • @DanielRunnakkoLöfgren 它适用于&lt;span class="url" id="yui_3_3_0_1_1350462992855206"&gt;www.&lt;b id="yui_3_3_0_1_1350462992855205"&gt;random.org&lt;/b&gt;&lt;/span&gt;
  • 我会进一步研究它。另外我知道我不应该使用正则表达式来处理 HTML,但是对于这个特定的任务,我被要求这样做,这就是我使用它的原因。
  • @DanielRunnakkoLöfgren 提出这个要求的人一定有病态的幽默感;无论如何,我已经更新了答案......希望它有所帮助。
  • @DanielRunnakkoLöfgren 您还应该确保匹配正确的内容...urlContents[2] 真的包含 Yahoo 页面吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-06
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
相关资源
最近更新 更多