使用DOM从第二个HTML表中提取数据,忽略第一个表

Pull data from second HTML table using DOM, ignore first table

本文关键字:数据 第一个 提取 DOM 第二个 HTML 使用      更新时间:2023-09-26

我有下面的PHP脚本,它是通过命令提示符运行的,如果一页上只有一个表,它会很好地工作,但如果我在一页上有两个表,我只会尝试取出第一个表,在某些情况下,我有没有办法忽略第一个表而只处理第二个表?

我无法控制HTML,因此无法使用ID来定位表。

HTML

<html>
</head>
...
</head>
<body>
    <table>
        <tr>
            <th>Problem Table</th>
        </tr>
        <tr>
            <td>Annoying table in the way!</td>
        </tr>
    </table>
    <hr/>
    <table>
        <tr>
            <th>ID</th>
            <th>Asset</th>
        </tr>
        <tr>
            <td>34234234</td>
            <td>Website3</td>
        </tr>
        <tr>
            <td>34234234</td>
            <td>Website4</td>
        </tr>
    </table>
</body>
</html>

PHP

$dom = new DOMDocument();
$html = $dom->loadHTMLFile($url);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(0)->getElementsByTagName('tr');
$cols = $rows->item(0)->getElementsByTagName('th');
$row_headers = null;
foreach($cols AS $node) {
    $row_headers[] = $node->nodeValue;
}
$table = array();
$rows = $tables->item(0)->getElementsByTagName('tr');
foreach($rows AS $row) {
    $cols = $row->getElementsByTagName('td');
    $row = array();
    $i = 0;
    foreach($cols AS $node) {
        if ($row_headers != null) {
            $row[$row_headers[$i]] = $node->nodeValue;
        }
        $i++;
    }
    if (!empty($row)) {
        $table[] = $row;
    }
}

我同意@GCC404的观点,即应该使用ID或类更好地针对元素,因为这很容易导致错误。

但是,如果您特别想针对最后一个表,您只需要将0替换为找到的项目数减去1:

$rows = $tables->item( $tables->length - 1 )->getElementsByTagName('tr');
// etc.

使用getElementsByTagName()时,可以使用DOMNodelist::item指定索引。

这可能只适用于您无法控制源HTML或确信始终有两个表的情况,但如果您可以控制HTML,我建议您只为每个表设置一个id/类。

$dom = new DOMDocument();
$html = $dom->loadHTMLFile($url);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(1)->getElementsByTagName('tr');
$cols = $rows->item(1)->getElementsByTagName('th');
$row_headers = null;
foreach($cols AS $node) {
    $row_headers[] = $node->nodeValue;
}
$table = array();
$rows = $tables->item(1)->getElementsByTagName('tr');
foreach($rows AS $row) {
    $cols = $row->getElementsByTagName('td');
    $row = array();
    $i = 0;
    foreach($cols AS $node) {
        if ($row_headers != null) {
            $row[$row_headers[$i]] = $node->nodeValue;
        }
        $i++;
    }
    if (!empty($row)) {
        $table[] = $row;
    }
}