2015-09-15 3 views
2

Je suis en train d'utiliser Web::Scraper pour analyser le code HTML suivant:Comment analyser ce HTML avec Web :: Scraper?

<div> 
<p><strong>TITLE1</strong> 
<br> 
DESCRIPTION1 
</p> 
<p><strong>TITLE2</strong> 
<br> 
DESCRIPTION2 
</p> 
<p><strong>TITLE3</strong> 
<br> 
DESCRIPTION3 
</p> 
</div> 

dans

 'test' => [ 
        { 
        'name' => 'TITLE1', 
        'desc' => 'DESCRIPTION1 ' 
        }, 
        { 
        'name' => 'TITLE2', 
        'desc' => 'DESCRIPTION2 ' 
        }, 
        { 
        'name' => 'TITLE3', 
        'desc' => 'DESCRIPTION3 ' 
        } 
       ] 

Je le code suivant mais je n'ai pas beaucoup de chance. « TEXT » lors du traitement « p » donne à la fois le texte et ce qui est entre « forte », par exemple

 'test' => [ 
        { 
        'name' => 'TITLE1', 
        'desc' => 'TITLE1 DESCRIPTION1 ' 
        } 
       ] 

plus son seul le premier élément.

Voici mon code.

use strict; 
use Web::Scraper; 
use Data::Dumper; 

my $html = q[<div> 
      <p><strong>TITLE1</strong> 
      <br> 
      DESCRIPTION1 
      </p> 
      <p><strong>TITLE2</strong> 
      <br> 
      DESCRIPTION2 
      </p> 
      <p><strong>TITLE3</strong> 
      <br> 
      DESCRIPTION3 
      </p> 
      </div> 
      ]; 

my $test = scraper { 
process 'div', 'test[]' => scraper { 
    process 'p strong', 'name' => 'TEXT'; 
    process 'p','desc' => 'TEXT';  
    }; 
}; 

    my $res = $test->scrape(\$html); 
    print Dumper($res); 

Merci.

Répondre

2

Deux points de votre code doivent être modifiés.

Pour obtenir uniquement le DESCRIPTION -text, utilisez xpath. //p/text() vous donnera les nœuds de texte directement sous p, donc ceux à l'intérieur du strong ne sont pas inclus.

Pour que tous les blocs de p apparaissent dans le tableau, et pas seulement le premier, faites en sorte que la première instruction soit sur div p. De cette façon, il saisit tous p à l'intérieur d'un div et pas seulement celui div.

my $test = scraper { 
    process 'div p', 'test[]' => scraper { 
     process 'p strong',   'name' => 'TEXT'; 
     process '//p/text()', 'desc' => ['TEXT', sub { s/^\s+|\s+$//g } ]; 
    }; 
}; 

sortie (avec Data::Printer):

\ { 
    test [ 
     [0] { 
      desc "DESCRIPTION1", 
      name "TITLE1" 
     }, 
     [1] { 
      desc "DESCRIPTION2", 
      name "TITLE2" 
     }, 
     [2] { 
      desc "DESCRIPTION3", 
      name "TITLE3" 
     } 
    ] 
} 
+0

merci qui a parfaitement fonctionné. – user1768233