Как переставить HTML-контент с HTML :: Treebuilder - PullRequest
2 голосов
/ 10 декабря 2011

Я пишу скрипт для перестановки html-контента, и я застрял с двумя проблемами. У меня есть эта HTML-структура, которая состоит из названий фильмов и лет выпуска с миниатюрами, сгруппированными в 5 столбцов. Я хочу создавать новые HTML-файлы с фильмами, сгруппированными по десятилетиям с 2011 по 1911 год, например, представить-2011; 2010-2001; 2000-1991; и т.д.

<table>
    <tr>
      <td class="basic" valign="top">
        <a href="details/267226.html" title="" id="thumbimage">
          <img src="images/267226f.jpg"/>
        </a>
        <br/>Cowboys &amp; Aliens &#160;(2011)
</td>
      <td class="basic" valign="top">
        <a href="details/267185.html" title="" id="thumbimage">
          <img src="images/267185f.jpg"/>
        </a>
        <br/>The Hangover Part II &#160;(2011)
</td>
      <td class="basic" valign="top">
        <a href="details/267138.html" title="" id="thumbimage">
          <img src="images/267138f.jpg"/>
        </a>
        <br/>Friends With Benefits &#160;(2011)
</td>
      <td class="basic" valign="top">
        <a href="details/266870.html" title="" id="thumbimage">
          <img src="images/266870f.jpg"/>
        </a>
        <br/>Beauty And The Beast &#160;(1991)
</td>
      <td class="basic" valign="top">
        <a href="details/266846.html" title="" id="thumbimage">
          <img src="images/266846f.jpg"/>
        </a>
        <br/>The Fox And The Hound &#160;(1981)
</td>
    </tr>


......

</table>

Единственная проблема, которую я не знаю, как решить, состоит в том, что после удаления фильмов, не соответствующих десятилетию, у меня остаются пустые теги 'tr' и позиции миниатюр, и я не знаю, как перегруппировать каждую строку в 5 заполненных столбцах. с 5 названиями. А также, как обрабатывать каждое десятилетие одним вызовом сценария. Спасибо.

use autodie;
use strict;
use warnings;
use File::Slurp;
use HTML::TreeBuilder;    

my $tree = HTML::TreeBuilder->new_from_file( 'test.html' );

for my $h ( $tree->look_down( class => 'basic' ) ) {

    edit_links( $h );      

    my ($year) = ($h->as_text =~ /.*?\((\d+)\).*/);
    if ($year > 2010 or $year < 2001) {
        $h->detach;
        write_file( "decades/2010-2001.html", \$tree->as_HTML('<>&',' ',{}), "\n" );
    }
}    

sub edit_links {
    my $h = shift;

    for my $link ( $h->find_by_tag_name( 'a' ) ) {
        my $href = '../'.$link->attr( 'href' );
        $link->attr( 'href', $href );
    }

    for my $link ( $h->find_by_tag_name( 'img' ) ) {
        my $src = '../'.$link->attr( 'src' );
        $link->attr( 'src', $src );
    }
}

1 Ответ

0 голосов
/ 10 декабря 2011

Подход ниже должен сделать то, что вы хотели в вопросе. Во время обработки HTML-файла настраивается хеш %decade, каждый ключ заканчивается годом десятилетия и значением arrayref соответствующих ячеек.

Второй цикл перебирает хеш и выводит файл для каждого десятилетия, окружая каждые 5 ячеек тегом <tr>.

use strict;
use HTML::TreeBuilder;
use File::Slurp;
use List::MoreUtils qw(part);

my $tree = HTML::TreeBuilder->new_from_file('test.html');

my %decade = ();

for my $h ( $tree->look_down( class => 'basic' ) ) {

    edit_links( $h );

    my ($year) = ($h->as_text =~ /.*?\((\d+)\).*/);
    my $dec = (int($year/10) + 1)  * 10;

    $decade{$dec} ||= [];
    push @{$decade{$dec}}, $h;
}

for my $dec (sort { $b <=> $a } keys %decade) {
    my $filename = "decades/" . $dec . "-" . ($dec - 9) . ".html";

    my $idx = 0;
    my @items = map { $_->as_HTML('<>&',' ',{}) } @{ $decade{$dec} };
    my $contents = join('',
        '<table>',
        (map { "<tr>@$_</tr>" } part { int($idx++ / 5) } @items),
        '</table>');

    write_file( $filename, $contents);
}

...
...