2014-02-21 2 views
2

Ниже приведен пример под рукой:Ассоциирование соседних элементов с Web в Perl :: Скребок

#!/usr/bin/perl 
use strict; 
use Web::Scraper; 
use Data::Dumper; 

my $html = q[ 
<html> 
    <body> 
    <div class="mainContainer"> 
     <div class="when">February 20, 2014</div> 
     <div class="name">Name 1</div> 
     <div class="desc">Desc 1</div> 
     <div class="when">February 21, 2014</div> 
     <div class="name">Name 2</div> 
     <div class="desc">Desc 2</div> 
     <div class="name">Name 3</div> 
     <div class="desc">Desc 3</div> 
     <div class="when">February 22, 2014</div> 
     <div class="name">Name 4</div> 
     <div class="desc">Desc 4</div> 
    </div> 
    </body> 
</html> 
]; 

my $scraper = scraper { 
    process ".when", "events[]" => scraper { 
     my $when = $_->content(); 
     my $hash = {}; 
     $hash->{$when}->{name} = "NAME"; 
     $hash->{$when}->{desc} = "DESC"; 
     return $hash; 
    }; 
}; 

my $result = $scraper->scrape($html); 

print Dumper($result); 

То, что я пытаюсь сделать, это связать даты с деталями событий. Как вы можете видеть, divs не вложены, поэтому это не так тривиально (по крайней мере для меня). Также каждое событие состоит из name и desc. Я не нашел способ связать смежные элементы в желаемой структуре с помощью селекторов css. Я решил, что мне понадобится пользовательская подпрограмма, чтобы вернуться к этим ассоциациям элементов. То, что я хотел бы получить что-то похожее на следующее:

[ 
'February 20, 2014' => [ 
    { 
    'name' => 'Name 1', 
    'desc' => 'Desc 1' 
    } 
], 
'February 21, 2014' => [ 
    { 
    'name' => 'Name 2', 
    'desc' => 'Desc 2' 
    }, 
    { 
    'name' => 'Name 3', 
    'desc' => 'Desc 3' 
    } 
], 
'February 22, 2014' => [ 
    { 
    'name' => 'Name 4', 
    'desc' => 'Desc 4' 
    } 
] 
] 

ответ

0

Вы могли бы лучше получать данные первого, а затем обрабатывать их после скребка. So ...:

my $scraper = scraper { 
    process ".when", "dates[]" => "TEXT"; 
    process ".name", "names[]" => "TEXT"; 
    process ".desc", "desc[]" => "TEXT"; 
}; 

my $result = $scraper->scrape($html); 

# Here you would start processing these 

my @dates = @{ $result->{dates} }; 
my @names = @{ $result->{names} }; 
my @info = @{ $result->{desc} }; 
my %events; 

for (my $i = 0; $i < scalar @dates; $i++) { 
    my $date = $dates[$i]; 
    my $name = $names[$i]; 
    my $info = $info[$i]; 
    if (exists $events{$date}) { 
    push @{ $events{$date} }, { 'name' => $name, 'desc' => $info }; 
    } 
    else { 
    $events{$date} = [{ 'name' => $name, 'desc' => $info}]; 
    } 
} 

% событий будут иметь данные, которые вам нужны. Все это предполагает, что вы все еще нуждаетесь в этом, и каждая дата события имеет имя и описание после него. Кроме того, я не тестировал это.

Смежные вопросы