【问题标题】:How do I extract data from a quoted-printable encoded HTML table?如何从带引号的可打印编码 HTML 表中提取数据?
【发布时间】:2012-06-08 15:06:18
【问题描述】:

我知道HTML::TableExtract 模块中有many other posts related,但它们都处于比我目前理解的更高的水平。我有一个来自电子邮件的非常小的表格(3 行 5 列),我想抓取第二行中的所有数据。但是,由于我对 Perl 的了解有限,我在在线阅读文档时遇到了很多麻烦。

表格如下所示:

Time      notspam    probablespam    likelyspam    spam
2012-05   10252205   62192           55995         3797710
Total     ""         ""              ""            ""

这是我要解析的代码的 sn-p。这是三行中的第二行:

<tr class=3DmailViewUnreadOdd>

<td  class=3DreportViewHeader align=3D"left">
=09
     2012-05
</td>
=20=20
=20=20=20=20
     <td align=3D'right' class=3D'mailViewRowReadEven'>
10252205
=20=20=20=20
</td>
=20=20
=20=20=20=20
     <td align=3D'right' class=3D'mailViewRowReadEven'>
62192
=20=20=20=20
</td>
=20=20
=20=20=20=20
     <td align=3D'right' class=3D'mailViewRowReadEven'>
55995
=20=20=20=20
</td>
=20=20
=20=20=20=20
     <td align=3D'right' class=3D'mailViewRowReadEven'>
3797710
=20=20=20=20
</td>
=20=20
</tr>

这是我到目前为止所尝试的。我在 HTML::TableExtract 页面上使用了一个示例,并对其进行了修改以满足我的需要。但它没有返回任何东西:

use HTML::TableExtract;
my $te = HTML::TableExtract->new(
    headers => [qw(notspam  probablespam  likelyspam  spam)]);
my $html = 'test.html';
$te->parse($html);
# Examine all matching tables
foreach $ts ($te->tables) {
    print "Table (", join(',', $ts->coords), "):\n";
    foreach $row ($ts->rows) {
        print join(',', @$row), "\n";
    }
}

我想提取日期(2012-05)和数字(10252205、62192、55995、3797710)并将它们存储在变量中。我应该使用深度和计数参数来提取数据吗?

【问题讨论】:

  • 好吧,我本来打算使用 HTML:Parse,但后来发现我应该使用 HTML:TableExtract。我尝试过使用深度和计数,但我不确定我是否做得对。老实说,我讨厌成为 SO 上的“那个人”,但我对 Perl 真的了解不多。我正在尝试将所有内容拼凑在一起并边走边学。我猜从我发现的情况来看,提取信息的最佳方式是按标题搜索,所以我会寻找“可能是垃圾邮件、可能是垃圾邮件、垃圾邮件等”。

标签: html perl parsing html-table


【解决方案1】:

这适用于您的示例数据。 (当针对完整的电子邮件运行时,它可能会捕获太多内容,但我只能使用部分 HTML 来做到这一点。)

use strictures;
use File::Slurp qw(read_file);
use MIME::QuotedPrint qw(decode_qp);
use Web::Query qw();

my $w = Web::Query->new_from_html(decode_qp read_file 'so10883053.html');
my @data = $w->find('.mailViewUnreadOdd > *')->text;
# (
#     " 2012-05 ",
#       10252205 ,
#          62192 ,
#          55995 ,
#        3797710
# )

不要像我在代码中展示的那样手动解码电子邮件,而应该使用非常高级的解析器,例如 Courriel

【讨论】:

  • 感谢您对大信的帮助。问题是这些数字会定期变化,所以我需要数据的位置,而不是文字值。抱歉,我没有提到这一点。
  • 然后edit your question 并非常具体地说明您对“位置”的含义。说明您将如何从示例数据中手动得出解决方案。
猜你喜欢
  • 2018-04-09
  • 2017-10-25
  • 1970-01-01
  • 2016-09-04
  • 2013-07-09
  • 2019-11-25
  • 2012-10-12
  • 2017-04-19
  • 1970-01-01
相关资源
最近更新 更多