【问题标题】:Using PHP and RegEx to fetch all option values from a site's source code使用 PHP 和 RegEx 从站点的源代码中获取所有选项值
【发布时间】:2011-05-14 08:32:25
【问题描述】:

我正在学习 RegEx 和网站抓取,并且有以下问题,如果得到解答,应该会大大加快我的学习过程。

我从一个网站以 htmlencoded 格式获取了表单元素。也就是说,我有 $content 字符串,所有标签都完好无损,如下所示:

$content = "<form name="sth" action="">
<select name="city">
<option value="one">One town</option>
<option value="two">Another town</option>
<option value="three">Yet Another town</option>
...
</select>
</form>

我想以这种方式获取网站上的所有选项:

array("One Town" => "one", "Another Town" => "two", "Yet Another Town" => "three" ...);

现在,我知道这可以通过操作字符串、切片、切块、在每个字符串中搜索子字符串等等来轻松完成,直到我拥有所需的一切。但我确信必须有一种更简单的方法来使用正则表达式,它应该立即从给定的字符串中获取所有结果。谁能帮我找到一个捷径?我搜索了网络上最好的正则表达式网站,但无济于事。

非常感谢

【问题讨论】:

    标签: php mysql regex web-crawler


    【解决方案1】:

    Best methods to parse HTML。在下面找到 DOM 解决方案:

    $dom = new DOMDocument;
    $dom->loadHTMLFile('http://example.com');
    $options = array();
    foreach($dom->getElementsByTagName('option') as $option) {
        $options[$option->nodeValue] = $option->getAttribute('value');
    }
    

    这个can be done with Regex 也是如此,但是当有大量可用于 PHP 的本地和第 3 方解析器时,我发现使用 Regex 编写可靠的 HTML 解析器并不实用。

    【讨论】:

    • 虽然上述方法没有像我预期的那样工作,但使用您链接的帖子中建议的 Zend_Dom 是可行的方法,因为无论如何我都是在 ZF 中构建项目的。太好了,非常感谢!
    【解决方案2】:

    如果它真的是连贯的 HTML,那么一个简单的正则表达式就可以了:

     preg_match('/<option\s+value="([^">]+)">([^<]+)/i', ...
    

    但是,使用 phpQuery 或 QueryPath 通常更简单、更可靠。

     $options = qp($html)->find("select[name=city]")->find("option");
     foreach ($options as $o) {
          $result[ $o->attr("value") ] = $o->text();
     }
    

    【讨论】:

      【解决方案3】:

      使用 SimpleXML:

      libxml_use_internal_errors(true);
      $load = simplexml_load_string($content);
      foreach ($load->xpath('//select/option') as $path)
          var_dump((string)$path[0]);
      

      【讨论】:

        【解决方案4】:

        我认为使用 DomXPath 比使用正则表达式更容易。 您可以尝试这样的事情(未经测试,因此可能需要一些调整)...

        <?php
        $content = '<form name="sth" action="">
                    <select name="city">
                    <option value="one">One town</option>
                    <option value="two">Another town</option>
                    <option value="three">Yet Another town</option>
                    </select>
                    </form>';
        
        $doc = new DOMDocument;
        $doc->loadhtml($content);
        $xpath = new DOMXPath($doc);
        $options = $xpath->evaluate("/html/body//option");
        for ($i = 0; $i < $options->length; $i++) {
                $option = $options->item($i);
                $values[] =  $option->getAttribute('value');                
        }
        var_dump($values);
        ?>
        

        【讨论】:

          【解决方案5】:
          <?php
          
          $content = '<form name="sth" action="">
          <select name="city">
          <option value="one">One town</option>
          <option value="two">Another town</option>
          <option value="three">Yet Another town</option>
          </select>
          </form>';
          
          preg_match_all('@<option value=\"(.*)\">(.*)</option>@', $content,$matches);
          
          echo "<pre>";
          print_r($matches);
          ?>
          

          现在 $matches 包含您要查找的数组,您可以非常轻松地将它们处理为结果。

          【讨论】:

          • 不建议使用正则表达式。上面的代码失败了&lt;option selected="selected" value="xyz"&gt;hello, world&lt;/option&gt;
          • 不建议 - 是的,但我从 Swader 的帖子中认为他想要一个正则表达式示例。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多