【问题标题】:Can't traverse DOM with simple_html_dom to find and iterate through table rows无法使用 simple_html_dom 遍历 DOM 来查找和遍历表行
【发布时间】:2016-09-22 21:56:33
【问题描述】:

我有一张带有theadtbody 的表——前几行是这样的:

<table class="general player-list-table">
    <thead>
        <tr>
            <th width="20"></th>
            <th class="header-name">
                <a href="playerlist.aspx?dpt=0&srt=1">Name</a>
            </th>
            <th width="20"></th>
            <th width="20"></th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=2">Club</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=3">Price</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=4">Rating</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=5" title="Games Played">PLD</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=6" title="Goals">GLS</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=7" title="Assists">ASS</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=8" title="Clean Sheets">CS</a>
            </th>
            <th>
                <a href="playerlist.aspx?dpt=0&srt=9" title="Goals Against">GA</a>
            </th>
            <th class="highlight">
                <a href="playerlist.aspx?dpt=0&srt=10" title="Month Points">MTH</a>
            </th>
            <th class="highlight header-tot">
                <a href="playerlist.aspx?dpt=0&srt=11" title="Overall total">TOT</a>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr class="on">
            <td class="first no-border">
                <div class="pos pos1"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/petr-cech.aspx">P Cech</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.2</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>34</td>
            <td>0</td>
            <td>0</td>
            <td>16</td>
            <td>31</td>
            <td class="highlight">2</td>
            <td class="highlight">35</td>
        </tr>
        <tr>
            <td class="first no-border">
                <div class="pos pos1"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/david-ospina.aspx">D Ospina</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.1</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>4</td>
            <td>0</td>
            <td>0</td>
            <td>2</td>
            <td>5</td>
            <td class="highlight">0</td>
            <td class="highlight">3</td>
        </tr>
        <tr class="on">
            <td class="first no-border">
                <div class="pos pos2"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/hector-bellerin.aspx">H Bellerin</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.2</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>36</td>
            <td>1</td>
            <td>5</td>
            <td>18</td>
            <td>33</td>
            <td class="highlight">4</td>
            <td class="highlight">52</td>
        </tr>
        <tr>
            <td class="first no-border">
                <div class="pos pos2"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/calum-chambers.aspx">C Chambers</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.1</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>4</td>
            <td>0</td>
            <td>0</td>
            <td>2</td>
            <td>3</td>
            <td class="highlight">0</td>
            <td class="highlight">5</td>
        </tr>
        <tr class="on">
            <td class="first no-border">
                <div class="pos pos2"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/kieran-gibbs.aspx">K Gibbs</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.2</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>3</td>
            <td>1</td>
            <td>0</td>
            <td>1</td>
            <td>6</td>
            <td class="highlight">0</td>
            <td class="highlight">2</td>
        </tr>
        <tr>
            <td class="first no-border">
                <div class="pos pos2"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/nacho-monreal.aspx">N Monreal</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.3</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>36</td>
            <td>0</td>
            <td>3</td>
            <td>17</td>
            <td>34</td>
            <td class="highlight">4</td>
            <td class="highlight">42</td>
        </tr>
        <tr class="on">
            <td class="first no-border">
                <div class="pos pos3"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/gabriel-armando-de-abreu.aspx">Gabriel</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.2</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>19</td>
            <td>1</td>
            <td>0</td>
            <td>10</td>
            <td>18</td>
            <td class="highlight">2</td>
            <td class="highlight">24</td>
        </tr>
        <tr>
            <td class="first no-border">
                <div class="pos pos3"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/laurent-koscielny.aspx">L Koscielny</a>
            </td>
            <td class="highlight"></td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.5</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>32</td>
            <td>4</td>
            <td>0</td>
            <td>15</td>
            <td>31</td>
            <td class="highlight">2</td>
            <td class="highlight">43</td>
        </tr>
        <tr class="on">
            <td class="first no-border">
                <div class="pos pos3"></div>
            </td>
            <td class="highlight">
                <a href="/Classic/Stats/Player/per-mertesacker.aspx">P Mertesacker</a>
            </td>
            <td class="highlight">
                <div class="right playerstatus doubtful" title="Hamstring"></div>
            </td>
            <td>
                <div class="left club-tiny club-tiny-arsenal"></div>
            </td>
            <td>
                <a href="/Classic/Stats/Club/arsenal.aspx">ARS</a>
            </td>
            <td class="highlight">4.4</td>
            <td>
                <div class="chilli normal"></div>
            </td>
            <td>23</td>
            <td>0</td>
            <td>0</td>
            <td>9</td>
            <td>24</td>
            <td class="highlight">0</td>
            <td class="highlight">17</td>
        </tr>
        <!-- etc -->

我正在尝试遍历每个tbody &gt; tr,从每个单元格中输出某些值,例如:

  • 第一个单元格中没有任何内容
  • 第二个单元格中a 元素的明文
  • 第三个和第四个单元格中什么都没有
  • 第五个单元格中a 元素的明文
  • 第六个单元格的明文,

为了实现这一点,我使用了simple_html_dom 库。

我的代码如下:

    foreach($dom->find("table.player-list-table tbody tr") as $row){
            $r["name"] = $row->find("td", 1)->find("a")->plaintext;
            $r["club"] = $row->find("td", 4)->find("a")->plaintext;
            $r["valu"] = $row->find("td", 5)->plaintext;

            print_r($r);
    }

但是,这会输出:

PHP 致命错误:未捕获的错误:调用 /var/www/html/.../foo.php:28 中 null 上的成员函数 find()

哪个指向foreach下的第一行:

$r["name"] = $row->find("td", 1)->find("a")->plaintext;

我怎样才能做到这一点?

【问题讨论】:

    标签: php parsing dom


    【解决方案1】:

    文档可能存在一些问题, 首先,您需要向 tbody 添加一个类,因为当您使用 tbody 标记查找行时,它还包括该行的行,这就是您收到此错误的原因。 tbody 标记现在更改为

    <tbody class="tbody">
    

    和foreach循环也改为

    foreach($dom->find("table.player-list-table .tbody tr") as $row){
    

    好的,现在它显示 .tbody 中的所有行。

    但是现在另一个问题,当我解析行并为 a 标签调用 find 函数时,它返回当前行中所有 a 的对象,意味着如果有 3 a 连续然后对象将为每个 a 包含 3 个对象,您必须定位第一个对象,然后调用 plaintext 以获取其内容,现在您在 foreach 循环中的代码也更改为

    $name = $row->find("td", 1)->find("a");
    $r["name"] = $name[0]->plaintext;
    $club = $row->find("td", 4)->find("a");
    $r["club"] = $club[0]->plaintext;
    $r["value"] = $row->find("td", 5)->plaintext;
    

    我使用的是 PHP 5.3.10 版本,所以我必须使用临时变量来存储对象。

    另外,如果你不想给 tbody 添加类,你必须编辑 simple_html_dom.php,这里是如何处理它https://stackoverflow.com/a/4062007/3303041

    希望这可以帮助您解决问题。

    【讨论】:

    • 谢谢 - 我修改了你的代码,使每一对成为一行,例如:$r["name"] = $row-&gt;find("td", 1)-&gt;find("a",0)-&gt;plaintext; 通过指定 "a",0) 我不需要将它存储在变量中!
    • 好吧,我没用过,但它似乎是 PHP 的好工具,我会在接下来的项目中尝试使用它:)
    猜你喜欢
    • 2010-12-07
    • 2010-09-21
    • 2021-08-26
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多