使用perl中的HTML :: TableExtract从HTML中提取具有特定元素的表行

时间:2011-07-30 11:54:50

标签: html perl html-table

我已经了解了正则表达式无法充分解析html之前的困难方法,然后才发布帖子。

我正在尝试从位于表格中的网页中提取未读取的PM。它是页面上唯一被请求的表,因此该部分很好。 每行是关于PM的一组列。 TR的类通知未读/读PM。 - 抓住我的是什么。

我尝试使用HTML :: TableExtract,几乎完美地工作,除了我无法弄清楚如何检查TR元素。

示例表结构:

<table>
    <tr class="header">
        <td></td>
        <td>Subject</td>
        <td>Sender</td>
        <td>Date</td>
    </tr>
    <tr class="unread">
        <td>checkbox for multi-edit stuff</td>
        <td>Example of an unread PM</td>
        <td>Me</td>
        <td>Jul 30, 2011</td>
    </tr>
    <tr class="read">
        ....   
    </tr>
</table>

使用HTML :: TableExtract我能够获得除未读/读类之外的所有内容。 像这样:

$t = HTML::TableExtract->new(keep_html);
$t->parse($lwp_data);
foreach $t2 ($t->tables) {
    foreach $row ($t2->rows) {
#Can't find a way to search for <tr class="unread". As
#Attribute data is stripped at this point by HTML::TableExtract

        #This now shows EVERY PM in the list
        print join(',', @$row), "\n";
    }
 }

我怎样才能解析出来,只获得带有class =“unread”的TR?

搜索导致过于复杂的答案或答案,但并未完全解决我的问题。

这是我用来获得我想要的最新方法(而且正在工作,我只是想知道如何更好地做到这一点):

 while ($page =~ m/(unreadpm.*?\/tr)/sg) {
      $data = $1;
      if ($data =~ m(value="(\d+)".*?<a href="(inbox.php\?action=viewconv&amp;id=\d+)">(.*?)</a>\n</strong>\s+</td>\n\s+<td>(.*?)</td>)sg) {
           my ($id,$link,$subject,$user) = ($1, $2, $3, $4);
           if ($user =~ m(user\.php\?id=\d+">(.*?)</a>)) {
                $user = $1;
           }

           if (grep $_ eq $id, @ids) {
                print "Message ID: $id already listed\n"
           } else {
                print "Emailing - Subject: $subject by $user. ID: $id Link: $link ...";
                send_email($subject,$user,$link);
                print "done.\n";
                push @ids, $id;
           }
      }
 }

2 个答案:

答案 0 :(得分:1)

我可以推荐HTML::TreeBuilderXML::LibXML一起完成这项工作。

my $tree = HTML::TreeBuilder->new_from_content( $html );
my $xml  = $tree->as_XML;
my $doc = XML::LibXML->load_xml(string => $xml);

然后,您可以使用findvalue使用XPath表达式查找<tr>个节点。

使用HTML::Selector::XPath,您甚至可以使用CSS选择器转到<tr>

答案 1 :(得分:-1)

如果我理解了这个问题,那么我会做一些事情:

@html_lines = (use curl or otherwise to retrieve the html)

$GET_LINE = 0;

foreach $line (@html_lines)
{
  if ($line =~ /\<tr class="unread"\>/)
  {
      $GET_LINE = 1;
      next;
  }

  if ( ($line =~ |\</tr\>|) && ($GET_LINE) ) 
  { 
      $GET_LINE = 0;
      next;
  }

  if ($GET_LINE)
  {
     #process the <td> lines
  }
}

注意:我不保证语法是正确的,但你得到了图片......