【问题标题】:PHP: Simple HTML Dom parser - Parse HTML table with headers/uneven body rowsPHP:简单的 HTML Dom 解析器 - 解析带有标题/不均匀正文行的 HTML 表格
【发布时间】:2018-03-23 14:19:48
【问题描述】:

我有一个格式如下的 HTML 表格: 如您所见,第一个 Header 1 有一个 Row 1 与之关联。第二个 Header 2 有两行 - 第 2 行、第 3 行与其关联。标题 3 具有与之关联的第 4 行、第 5 行、第 6 行。

<table>
<thead>
    <tr>
        <th>Header 1</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 1
            </td>
        </tr>
</tbody>
<thead>
    <tr>
        <th>Header 2</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 2
            </td>
        </tr>
        <tr>
            <td>
                Row 3
            </td>
        </tr>

</tbody>
<thead>
    <tr>
        <th>Header 3</th>
    </tr>
</thead>
<tbody>
        <tr>
            <td>
                Row 4
            </td>
        </tr>
        <tr>
            <td>
                Row 5
            </td>
        </tr>
        <tr>
            <td>
                Row 6
            </td>
        </tr>
</tbody>

我想使用 PHP Simple HTML Dom 解析器来获取以下数据:

Header 1, Row 1
Header 2, Row 2, Row 3
Header 3, Row 4, Row 5, Row 6

当我使用解析器获取标签时,它们都存储在一个数组中。当我执行 foreach 循环时,所有其他标签都存储在另一个数组中。循环时如何保留标题与行的关联?

【问题讨论】:

  • 有什么理由不使用内置的 DOMDocument 接口?
  • 请出示您的代码。你指的是哪个foreach?

标签: php html parsing simple-html-dom


【解决方案1】:

您可以使用标准的 DOMDocument 接口来执行此操作。如果您的 HTML 存储在变量 $html 中,请执行以下操作:

$dom = new DOMDocument();
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('tr') as $row) {
    if ($row->parentNode->tagName === 'thead') $arr[] = [];
    $arr[count($arr)-1][] = trim($row->textContent);
}

上面运行后,变量$arr会有这样的内容:

[
    ['Header 1', 'Row 1'],
    ['Header 2', 'Row 2', 'Row 3'],
    ['Header 3', 'Row 4', 'Row 5', 'Row 6']
]

【讨论】:

    【解决方案2】:

    如果没有看到您现有的 php 代码,很难确切地说出如何更改您所拥有的。但是这样的事情适用于您的用例:

    //Assuming $html has been set to your html block
    $heads = $html->find('thead');
    $result = array();
    
    foreach($heads as $head){
        $headerText = $head->find('th')[0]->innerText;
        $result[$headerText] = array();
        $rows = $head->next_sibling()->find('td');
        foreach($rows as $row){
            $result[$headerText][] = $row->innerText;
        }
    }
    
    //Output
    foreach($result as $header => $rows){
        echo $header . ': ' . implode(',', $rows);
    }
    

    一些警告,上面是您想要做的一个简单示例。这是一个相当幼稚的实现。例如。它假定给定的thead 永远只有1 个th

    另外,如果回显它确实是您想要做的,那么直接在解析循环中回显会更有效。我将输出分开,因为我假设您要做的不仅仅是将其打印到屏幕上。

    请注意,使用本机 dom 解析器执行此类操作相当简单,我假设您出于其他原因需要使用简单的 html dom。

    【讨论】:

    • 谢谢,它运行良好。 @trincot 的解决方案也很有效。
    猜你喜欢
    • 2017-03-29
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多