HTML::Query 如何在 perl 5 中自动完成无效 HTML?

How HTML::Query autocomplete invalid HTML in perl 5?

我有无效的 HTML 代码,在 thead 中缺少 tr。尽管如此,我正在尝试使用 HTML::Query select 这个 HTML 的元素,但是 select 或有违反直觉的行为。

这是我的代码:

#!/usr/bin/env perl

require HTML::Query;
use JSON;

my $q = HTML::Query->new( text => '
<table>
    <thead>
        <th>A</th>
        <th>B</th>
        <th>C</th>
    </thead>
    <tbody>
    <tr>
        <td>E</td>
        <td>F</td>
        <td>G</td>
    </tr>
    </tbody>
</table>
' );

my %data = (
    tr => $q->query('tr')->first->as_trimmed_text,
    tbody => $q->query('tbody')->first->as_trimmed_text
);

print JSON->new->utf8(0)->encode( \%data );

结果:

{
  "tbody": "",
  "tr": "BC"
}

当然,如果我使用正确的 HTML 代码但缺少 tr:

<table>
    <thead>
    <tr>
        <th>A</th>
        <th>B</th>
        <th>C</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>E</td>
        <td>F</td>
        <td>G</td>
    </tr>
    </tbody>
</table>

然后程序打印疑似直观输出:

{
  "tr": "ABC",
  "tbody": "EFG"
}

我的问题:

我找到了部分答案。添加到散列 %data 对:

html => $q->as_HTML

我可以看到无效 HTML 这个结果:

<html>
    <head></head>
    <body>
        <table>
            <thead></thead>
            <th>A</th>
            <tr>
                <th>B</th>
                <th>C</th>
                <tbody></tbody>
            </tr>
            <tr>
                <td>E</td>
                <td>F</td>
                <td>G</td>
            </tr>
        </table>
    </body>
</html>

所以我知道无效HTML是如何转换的

在我看来,它是可以改变的。 Link 创建问题:

https://github.com/abw/HTML-Query/issues/8

我是这个包的维护者。

HTML::Query 在 HTML::Tree 提供的解析功能之上提供了选择器魔法。 HTML::Query 本身不提供解析。您的问题出在 HTML::Tree,而不是 HTML::Query.

HTML:树在很大程度上早于规范一致性。它最初是在 IE 统治互联网 (1999) 并根据 "real world" 用法处理 HTML 时创建的。它在处理 HTML 4 个文档方面做得很好,但是正如您所注意到的,非常规标记存在一些问题,这些标记在 HTML 4 中是合法的。没有办法处理这些边缘情况,库不能也不会处理它们,因为有成千上万的组织依赖现有的实施来继续像以前一样工作。

HTML::Tree 不正确支持 HTML5。底层库的作者 HTML::TagSet 拒绝支持它,并与任何提供解决方案或提出接管库的人争论(或忽略)。这种立场有效地阻止了所有衍生项目正确处理 HTML5 - HTML::Query 和 CSS::Inliner 也不例外。

至于建议使用 HTML::HTML5::Parser 或 "whatever other Perl modules that provide an HTML parser" - 我欢迎补丁。话虽这么说:没有充分维护的 Perl 库可以为 table 带来 HTML::Tree 所做的事情,因此任何此类尝试都可能会失败,但让我们看看您能想出什么。