【问题标题】:Simple_DOM question about finding classes关于查找类的 Simple_DOM 问题
【发布时间】:2011-05-21 23:56:01
【问题描述】:

我正在尝试做一个简单的提取,但我总是得到不可预测的结果。

我有这个 HTML 代码

<div class="thread" style="margin-bottom:25px;"> 

<div class="message"> 

<span class="profile">Suzy Creamcheese</span> 

<span class="time">December 22, 2010 at 11:10 pm</span> 

<div class="msgbody"> 

<div class="subject">New digs</div> 

Hello thank you for trying our soap. <BR>  Jim.

</div> 
</div> 


<div class="message reply"> 

<span class="profile">Lars Jörgenmeier</span> 

<span class="time">December 22, 2010 at 11:45 pm</span> 

<div class="msgbody"> 

I never sold you any soap.

</div> 

</div> 

</div> 

我正在尝试从“msgbody”中提取外部文本,但前提是“profile”等于某个值。像这样。

$contents  = $html->find('.msgbody');
$elements = $html->find('.profile'); 

           $length = sizeof($contents);

           while($x != sizeof($elements)) {

            $var = $elements[$x]->outertext;

                        //If profile = the right name
            if ($var = $name) {

                                    $text = $contents[$x]->outertext;
                echo $text;

            }



            $x++;
         }    

我从错误的个人资料中获取文本,而不是那些具有我需要的关联的个人资料。 有没有办法只用一行代码提取所需的信息?

如果 span-profile = "正确的名称" 那么 拉出它的 div-msgbody

【问题讨论】:

    标签: php html class object simpledom


    【解决方案1】:

    好的,我将使用DOMXpath 进行此操作。我不确定“外部文本”应该是什么意思,但我会满足这个要求:

    如果 span-profile = "正确的名称" 然后拉它的 div-msgbody

    首先,这是我使用的缩小的 HTML 测试用例:

    <html>
    <body>
    <div class="thread" style="margin-bottom:25px;"> 
    
    <div class="message"> 
    
    <span class="profile">Suzy Creamcheese</span> 
    
    <span class="time">December 22, 2010 at 11:10 pm</span> 
    
    <div class="msgbody"> 
    
    <div class="subject">New digs</div> 
    
    Hello thank you for trying our soap. <BR>  Jim.
    
    </div> 
    </div> 
    
    
    <div class="message reply"> 
    
    <span class="profile">Lars Jörgenmeier</span> 
    
    <span class="time">December 22, 2010 at 11:45 pm</span> 
    
    <div class="msgbody"> 
    
    I never sold you any soap.
    
    </div> 
    
    </div> 
    
    </div>
    </body>
    </html>
    

    因此,我们将为此进行 XPath 查询。让我们展示整个事情,然后分解它:

    $messages = $xpath->query("//span[@class='profile' and contains(.,'$profile_name')]/../div[@class='msgbody']");
    

    故障:

    //跨度

    给我跨度

    //span[@class='profile']

    给我班级所在的跨度 简介

    //span[@class='profile' 和 包含(.,'$profile_name')]

    给我班级所在的跨度 轮廓和跨度的内部 包含$profile_name,这是 你的名字

    //span[@class='profile' 和 包含(.,'$profile_name')]/../

    给我班级所在的跨度 轮廓和跨度的内部 包含$profile_name,这是 你的名字现在上升一个层次, 这让我们到达<div class="message">

    //span[@class='profile' 和 包含(.,'$profile_name')]/../div[@class='msgbody']

    给我班级所在的跨度 轮廓和跨度的内部 包含$profile_name,这是 你的名字现在上升一个层次, 这让我们到达<div class="message"> 最后,给我 &lt;div class="message"&gt; 下的所有 div 其中类是 msgbody

    那么,下面是 PHP 代码示例:

    $doc = new DOMDocument();
    $doc->loadHTMLFile("test.html");
    
    $xpath = new DOMXpath($doc);
    $profile_name = 'Lars Jörgenmeier';
    $messages = $xpath->query("//span[@class='profile' and contains(.,'$profile_name')]/../div[@class='msgbody']");
    foreach ($messages as $message) {
      echo trim("{$message->nodeValue}") . "\n";
    }
    

    XPath 就像这样非常强大。我建议查看basic tutorial,如果您想查看更高级的用法,可以查看XPath standard

    【讨论】:

    • 谁有很多简洁的信息。感谢 xpath 转换。我喜欢 Simple_DOM,但它会破坏内存!
    • 另外,我注意到你必须在标题中插入这个来获取那些特殊字符,例如 Jörgenmeier 来传递 XPath。
    • &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/&gt;
    • @user734063 嗯很有趣.. 老实说,您可能只需要 &lt;meta http-equiv="Content-Type" ....&gt; 位。它很可能对我有用,因为我将文件保存在本地并默认设置了 UTF-8。
    【解决方案2】:

    这是一个简单的 HTML DOM 工作示例。

    我更改了您的示例 html,因此 Suzy Creamcheese 的配置文件不止一个,如下所示:(文件:test_class_class.htm)

     <div class="message"> 
       <span class="profile">Suzy Creamcheese</span> 
       <span class="time">December 22, 2010 at 11:10 pm</span> 
       <div class="msgbody"> 
         <div class="subject">New digs</div> 
           Hello thank you for trying our soap. <BR>  Jim.
         </div> 
       </div> 
    
       <div class="message reply"> 
         <span class="profile">Lars Jörgenmeier</span> 
         <span class="time">December 22, 2010 at 11:45 pm</span> 
         <div class="msgbody"> 
           I never sold you any soap.
         </div> 
       </div> 
     </div>
    
     <div class="message"> 
       <span class="profile">Suzy Yogurt</span> 
       <span class="time">December 22, 2010 at 11:10 pm</span> 
       <div class="msgbody"> 
         <div class="subject">No Creamcheese</div> 
           This is not Suzy Creamcheese <BR>  Jim.
         </div> 
       </div> 
    
       <div class="message reply"> 
         <span class="profile">Suzy Creamcheese</span> 
         <span class="time">December 22, 2010 at 11:45 pm</span> 
         <div class="msgbody"> 
           A reply from Suzy Creamcheese.
         </div> 
       </div> 
     </div>
    
    </div>
    

    这是我使用 Simple HTML DOM 进行的测试: 包括('simple_html_dom.php');

    function getMessage_for_profile($iUrl,$iProfile)
    {
        // create HTML DOM
        $html = file_get_html($iUrl);
    
        // get text elements
        $aoProfile = $html->find('span[class=profile]'); 
        echo "Found ".count($aoProfile)." profiles.<br />";
    
        foreach ($aoProfile as $key=>$oProfile)
        {
          if ($oProfile->plaintext == $iProfile)
          {
            echo "<b>Profile ".$key.": ".$oProfile->plaintext."</b><br />";
    // Using $e->next_sibling ()
            $oCurrent = $oProfile;
            while ($oNext = $oCurrent->next_sibling())
            {
               if ( $oNext->class == "msgbody" )
               {
                 echo "<hr />";
                 echo $oNext->outertext;
                 echo "<hr />";
               }
               $oCurrent = $oNext;
            }
          }         
        }
    
        // clean up memory
        $html->clear();
        unset($html);
    
        return;
    }
    // --------------------------------------------
    // test it!
    // user_agent header...
    ini_set('user_agent', 'My-Application/2.5');
    
    getMessage_for_profile('test_class_class.htm','Suzy Creamcheese');
    echo "<br /><br /><br />";
    getMessage_for_profile('test_class_class.htm','Suzy Yogurt');
    

    我的输出是:

    Found 4 profiles.
    Profile 0: Suzy Creamcheese
    --------------------------------
    New digs
    Hello thank you for trying our soap.
    Jim.
    ---------------------------------
    Profile 3: Suzy Creamcheese
    ---------------------------------
    A reply from Suzy Creamcheese.
    ---------------------------------
    
    
    
    Found 4 profiles.
    Profile 2: Suzy Yogurt
    ---------------------------------
    No Creamcheese
    This is not Suzy Creamcheese
    Jim.
    ---------------------------------
    

    看看它可以用简单的 HTML DOM 来完成,因为我已经知道 DOM 是如何工作的......或者足以惹上麻烦......我不必学习任何已知的语法!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-27
      • 2020-08-23
      • 2020-08-04
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      相关资源
      最近更新 更多