【问题标题】:How to parse text fragments located outside tags (inbetween tags) by simplehtmldom?如何通过 simplehtmldom 解析位于标签外部(标签之间)的文本片段?
【发布时间】:2010-04-14 15:15:17
【问题描述】:

我正在使用 simplehtmldom 解析 html,但我被困在解析位于任何标签之外(但在两个不同标签之间)的纯文本:

<div class="text_small">
 <b>Аdress:</b> 7 Hange Road<br>    
 <b>Phone:</b> 415641587484<br>    
 <b>Contact:</b> Alex<br>    
 <b>Meeting Time:</b> 12:00-13:00<br>
</div>

是否可以获得地址、电话、联系人、会议时间的这些值? 我想知道是否有机会将 CSS 选择器传递给 nextSibling/previousSibling 函数...

foreach($html->find('div.text_small') as $div_descr) 
 {
   foreach($div_descr->find('b') as $b) 
 {
 if ($b->innertext=="Аdress:") {//someaction
                }
 if ($b->innertext=="Phone:") { //someaction
                }
        if ($b->innertext=="Contact:") { //someaction
                }
        if ($b->innertext=="Meeting Time:") { //someaction
                }
    }
 }

我应该用什么来代替“someaction”?

更新。是的,我无权编辑目标页面。否则,值得吗? :)

【问题讨论】:

    标签: php parsing


    【解决方案1】:

    可能有一个更简单的解决方案。 (也许使用 simple_html_dom 以外的其他东西)

    我还没有找到合适的选择器,nextSibling() 只返回下一个兄弟元素。 (这有点奇怪。simple_html_dom_node 存储了两个数组,$children 和 $nodes。文本节点在 $nodes 中,但不在 $children 中。并且 next_sibling() 对 $children 进行操作)。
    但是由于 $nodes 是 simple_html_dom_node 的公共属性,因此您需要自己编写一些迭代器。

    <?php
    require_once 'simplehtmldom/simple_html_dom.php';
    $html = str_get_html('<html><head><title>...</title></head><body>
      <div class="text_small">
        <b>Adress:</b> 9 Hange Road<br>    
        <b>Phone:</b> 999641587484<br>    
        <b>Contact:</b> Alex<br>    
        <b>Meeting Time:</b> 12:00-13:00<br>
      </div>
      <div class="text_small">
        <b>Adress:</b> 8 Hange Road<br>    
        <b>Phone:</b> 888641587484<br>    
        <b>Contact:</b> Bob<br>    
        <b>Meeting Time:</b> 13:00-14:00<br>
      </div>
    </body></html>');
    
    foreach($html->find('div.text_small') as $div) {
      $result = parseEntry($div);
      foreach($result as $r) {
        echo "'$r[name]' - '$r[text]'\n";
      }
      echo "========\n"; 
    }
    
    function parseEntry(simple_html_dom_node $div) {
      $result = array();
      $current = null;
      for($i=0; $i<count($div->nodes); $i++) {
        if ( HDOM_TYPE_ELEMENT===$div->nodes[$i]->nodetype) {
          if ( !is_null($current) ) {
            $result[] = $current;
            $current = null;
          }
          if ('b'===$div->nodes[$i]->tag) {
            $current = array('name'=>$div->nodes[$i]->text(), 'text'=>'');
          }
        }
        else if (HDOM_TYPE_TEXT===$div->nodes[$i]->nodetype && !is_null($current)) {
          $current['text'] .= $div->nodes[$i]->text();
        }
      }
      if ( !is_null($current) ) {
        $result[] = $current;
      }
      return $result;
    }
    

    打印

    'Adress:' - ' 9 Hange Road'
    'Phone:' - ' 999641587484'
    'Contact:' - ' Alex'
    'Meeting Time:' - ' 12:00-13:00'
    ========
    'Adress:' - ' 8 Hange Road'
    'Phone:' - ' 888641587484'
    'Contact:' - ' Bob'
    'Meeting Time:' - ' 13:00-14:00'
    ========
    

    在其他人找到更简单的解决方案之前,您可能希望以此为起点。

    【讨论】:

    • 谢谢!有用!但是,如果我有几个“div.text_small”容器要解析,我总是会从最后一个容器中获取值! :(
    • 谢谢!您能否告知我如何将所有这些(所有这些结果)收集到一个特定的数组或 json 数据中,例如:{“1”:“{“地址”:“汉格路 9 号”,“电话”:“999641587484” ,"联系方式":"Alex","开会时间":"12:00-13:00"}","2":"{"地址":"汉格路8号","电话":"888641587484", "联系方式":"Bob","会议时间":"13:00-14:00"}....等等.."} ?
    【解决方案2】:

    如果您可以将跨度标签放在标签内的值上。也许你可以处理它然后

    由于&lt;span&gt; 对这些值不做任何事情,直到你给它一些风格

    【讨论】:

    • 很遗憾,我不能这样做,因为我没有编辑目标页面的权限:(
    猜你喜欢
    • 2021-07-15
    • 2019-12-06
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多