HTML :: TokeParser

HTML рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╕рдордп рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕реЗ рдПрдХ HTML :: TokeParser рд╣реИред рдпрд╣ рдореЙрдбреНрдпреВрд▓ рд╕рдВрдкреВрд░реНрдг HTML рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рдЯреЛрдХрди рдореЗрдВ рддреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдк рдмрд╛рдж рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЗрдП рдХреБрдЫ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред рд╡реЗрдмрд╕рд╛рдЗрдЯ habrahabr.ru рдХреЛ рд▓реЗрдВ

рдЙрджрд╛рд╣рд░рдг 1. рдЖрдкрдХреЛ рдкреВрд░реНрдг рд▓реЗрдЦ рдХреЗ рд▓рд┐рдВрдХ рдХреА рд╕реВрдЪреА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдкрд╣рд▓рд╛ рд╡рд╛рд▓рд╛ред рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдореЗрдЯрд╛ рдЯреИрдЧ рдХреЛ рджреЗрдЦреЛ, Habr рдХреЗ рд▓рд┐рдП рдпрд╣ UTF-8 рд╣реИ

<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 


рджреВрд╕рд░рд╛ рд╡рд╛рд▓рд╛ред рд╡реЗрдм рдкреЗрдЬ рдХреЛ рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВред рдПрдХ рдЫреЛрдЯреА рд╕реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдирд╛

 use strict; use warnings; use HTML::TokeParser; use Data::Dumper; open (my $f,"<", $ARGV[0]) ; my $p = HTML::TokeParser->new($f); while (my $token = $p->get_token()) { print Dumper ($token); } 


рд╣рдо рдЕрдкрдиреА рд╕рд╣реЗрдЬреА рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЗрдирдкреБрдЯ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдбреЗрдЯрд╛ рдХреЛ STDOUT рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдХреБрдЫ рдРрд╕рд╛ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣рд┐рдП

 $VAR1 = [ 'T', ' ', '' ]; $VAR1 = [ 'D', '<!DOCTYPE html>' ]; $VAR1 = [ 'T', ' ', '' ]; $VAR1 = [ 'S', 'html', { 'xmlns' => 'http://www.w3.org/1999/xhtml', 'xml:lang' => 'ru' }, [ 'xmlns', 'xml:lang' ], '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">' ]; 


рдЖрджрд┐ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдбреАрдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдПрдЧреАред

рддреАрд╕рд░рд╛ред рд╣рдо рдлрд╛рдпрд░рдмрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд▓реЗрдЦ рдХреЗ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд▓рд┐рдВрдХ рдХреНрдпрд╛ рд╣реИред рдпрд╣реА рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ

 <a href="http://habrahabr.ru/post/163525/#habracut" class="button habracut">  тЖТ</a> 


рд╣рдо рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХрдХреНрд╖рд╛ = "рдмрдЯрди рд╣реИрдмрд░рдХреБрдЯ" рдХреЗ рд▓рд┐рдП рд╕рднреА рд▓рд┐рдВрдХ рдЖрд╕рд╛рдиреА рд╕реЗ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдЪрд░рдг 2 рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдмрдЯрди habracut рд▓рд╛рдЗрди рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдо рдЕрдкрдирд╛ рдкрд╛рд░реНрд╕рд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдореИрдВ рдЖрдорддреМрд░ рдкрд░ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддрд╛ рд╣реВрдВред Parser рдХреЛ HTML рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╡рд╣реА рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ

Test.pl
 use strict; use warnings; use habr_parse; use LWP::UserAgent; use Data::Dumper; my $ua = LWP::UserAgent->new(); my $res = $ua->get("http://habrahabr.ru"); if ($res->is_success()) { my $parser = habr_parse->new(); # print Dumper ($res); my $conf = {}; $conf->{content} = $res->content; $conf->{cp} = 'utf8'; my $r = $parser->get_page_links($conf); print Dumper ($r); } 


Habr_parse.pm

 package habr_parse; use strict; use warnings; use HTML::TokeParser; use HTML::Entities; use Data::Dumper; use Encode; sub new { my $class = shift; my $self = {}; bless ($self, $class); } sub get_page_links { my $self = shift; my $conf = shift; my @data; # get internal format $conf->{content} = decode($conf->{cp},$conf->{content}); # print Dumper ($conf); decode_entities($conf->{content}); my $p = HTML::TokeParser->new(\$conf->{content}); while (my $token = $p->get_token()) { # we found our link if ($token->[0] eq 'S' && $token->[1] eq 'a' && defined ($token->[2]->{class}) && $token->[2]->{class}=~/^\s*button\s+habracut$/i) { push @data, $token->[2]->{href}; } } # print Dumper ($p); return \@data; } return 1; 


рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреА рдПрдХ рдкрдВрдХреНрддрд┐ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЪрд░рдг 2 рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдмрд╣реБрдд рдорджрдж рдХрд░рддреА рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдпрджрд┐ рдмрд╣реБрдд рд╕рд╛рд░реА рд╢рд░реНрддреЗрдВ рд╣реИрдВ)
  if ($token->[0] eq 'S' && $token->[1] eq 'a' && defined ($token->[2]->{class}) && $token->[2]->{class}=~/^\s*button\s+habracut$/i) 


рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рдВрдХ рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛ (рд╡рд░реНрдЧ рдорд╛рди) рд╣реИ , рдЬреЛ рдХрд╣реАрдВ рдФрд░ рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди HTML :: TokeParser рдХреА рд╢рдХреНрддрд┐ рд╡рд╣ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг 2 рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдЙрджрд╛рд╣рд░рдг 2. рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдлрд╛рдпрд░рдмрдЧ рдХреЗ рд╕рд╛рде, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╢реНрд░реЗрдгрд┐рдпрд╛рдВ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╡рд░реНрдЧ = 'рд╣рдм' рдХреЗ рд╕рд╛рде рдПрдХ div рдЯреИрдЧ рдХреЗ рдЕрдВрджрд░ рд╣реИрдВред

рдЪреВрдВрдХрд┐ рд╣рдо рдХреБрдХреАрдЬрд╝ рдФрд░ рдХрд┐рд╕реА рднреА рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЗ рдмрд┐рдирд╛ рд╕рд╛рдЗрдЯ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рд╣рдм рдХреА рд╕рджрд╕реНрдпрддрд╛ рдирд╣реАрдВ рджреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП, рд╢реАрд░реНрд╖рдХ рдХреЗ рд╕рд╛рде рд▓рд┐рдВрдХ = 'рдЖрдк рдЗрд╕ рд╣рдм рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рдирд╣реАрдВ рд▓реЗрддреЗ рд╣реИрдВ' рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдк рдЪрд░рдг 2 (рдЙрджрд╛рд╣рд░рдг 1) рдореЗрдВ рдмрдирд╛рдП рдЧрдП рд╣рдорд╛рд░реЗ рдбрдВрдк рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдХреМрди рд╕реЗ рдЯреБрдХрдбрд╝реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

 $VAR1 = [ 'S', 'a', { 'href' => 'http://habrahabr.ru/hub/photo/', 'title' => '     ', 'class' => 'hub ' }, [ 'href', 'class', 'title' ], '<a href="http://habrahabr.ru/hub/photo/" class="hub " title="     " >' ]; $VAR1 = [ 'T', '', '' ]; 


рдЕрдЧрд░ рд╣рдо рдкрд╣рд▓реА рдмрд╛рд░ рд╢реАрд░реНрд╖рдХ рдХреЗ рд╕рд╛рде рдПрдХ рд▓рд┐рдВрдХ рдкрд╛рддреЗ рд╣реИрдВ рддреЛ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ = 'рдЖрдк рдЗрд╕ рд╣рдм рдХреЗ рд▓рд┐рдП рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдм рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ' рд╣рдореЗрдВ рдЕрдЧрд▓рд╛ рдЯреЛрдХрди рдорд┐рд▓реЗрдЧрд╛ рдФрд░ рдЕрдЧрд░ рдпрд╣ рдЯреЗрдХреНрд╕реНрдЯ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕реЗрд╡ рдХрд░реЗрдВред

рдореИрдВ рдереЛрдбрд╝реА рдЕрд▓рдЧ рддрдХрдиреАрдХ рджрд┐рдЦрд╛рдКрдВрдЧрд╛, рдЬреЛ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдХрд┐ рд╣рдо рд╕реНрдЯреИрдХ рдкрд░ рдЯреЛрдХрди рдзрдХреЗрд▓рддреЗ рд╣реИрдВ, рдирд╡реАрдирддрдо рдЯреЛрдХрди рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рд╣рдореЗрдВ рд╡рд╣ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╣рдо рдЖрд╡рд╢реНрдпрдХ рдЯреЛрдХрди рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо unget_token () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдЖрдЗрдП рдПрдХ рдФрд░ рдкреИрдЯрд░реНрди рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рд╣рдореЗрдВ рдЬрд┐рд╕ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рдмрд╛рдж рд╕рдорд╛рдкрди рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рдЯреЛрдХрди рд╣реИ

 $VAR1 = [ 'T', '.   ', '' ]; $VAR1 = [ 'E', 'a', '</a>' ]; 


рдмрджрд▓реЗрдВ habr_parse.pm

 package habr_parse; use strict; use warnings; use HTML::TokeParser; use HTML::Entities; use Data::Dumper; use Encode; sub new { my $class = shift; my $self = {}; bless ($self, $class); } sub get_page_links { my $self = shift; my $conf = shift; my @data; # get internal format # $conf->{content} = decode($conf->{cp},$conf->{content}); # print Dumper ($conf); # decode_entities($conf->{content}); my $p = HTML::TokeParser->new(\$conf->{content}); my $tmp_conf = {}; while (my $token = $p->get_token()) { # we found our link if ($token->[0] eq 'S' && $token->[1] eq 'a' && defined ($token->[2]->{class}) && $token->[2]->{class}=~/^\s*button\s+habracut$/i) { $tmp_conf->{href} = $token->[2]->{href}; } elsif ($token->[0] eq 'S' && $token->[1] eq 'div' && defined ($token->[2]->{class}) && $token->[2]->{class} eq 'hubs') { my @next; my $found=0; #      $tmp_conf = {}; my $token = $p->get_token(); push @next, $token; #     div ( div   ). while ($next[$#next][1] ne 'div') { push @next, $p->get_token(); # print Dumper ($next[$#next][1]); #    if ($next[$#next][0] eq 'E' && $next[$#next][1] eq 'a') { #   T     if ($next[$#next-1][0] eq 'T') { # print $next[$#next-1][1] . "\n"; push @{$tmp_conf->{cats}}, $next[$#next-1][1]; $found = 1; } } } if (!$found) { #         $p->unget_token(@next); } push @data, $tmp_conf; } } # print Dumper ($p); return \@data; } return 1; 


рдкрд░рд┐рдгрд╛рдо

 $VAR1 = [ { 'cats' => [ '    IT', ' ' ], 'href' => 'http://habrahabr.ru/post/162053/#habracut' }, { 'cats' => [ '', ' ' ], 'href' => 'http://habrahabr.ru/post/163433/#habracut' }, { 'cats' => [ '  ', '.   ', ' ' ], 'href' => 'http://habrahabr.ru/post/163493/#habracut' }, { 'cats' => [ 'HTML', 'CSS' ], 'href' => 'http://habrahabr.ru/post/163429/#habracut' }, { 'cats' => [ '', '  Intel' ], 'href' => 'http://habrahabr.ru/company/intel/blog/162293/#habracut' }, { 'cats' => [ ' тАФ ', '', '   ' ], 'href' => 'http://habrahabr.ru/company/tm/blog/163483/#habracut' }, { 'cats' => [ '-', 'Open source' ], 'href' => 'http://habrahabr.ru/post/163425/#habracut' }, { 'cats' => [ '', ' ', 'Open source' ], 'href' => 'http://habrahabr.ru/post/148911/#habracut' }, { 'cats' => [ '' ], 'href' => 'http://habrahabr.ru/post/163445/#habracut' }, { 'cats' => [ '  ', ' ' ], 'href' => 'http://habrahabr.ru/post/163525/#habracut' } ]; 


Unget_token () рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╛рди рджреГрд╖реНрдЯрд┐рдХреЛрдг рднреА рдЖрдкрдХреЛ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рд╕реНрддрд░ рджреНрд╡рд╛рд░рд╛ рдЯреЛрдХрди рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдПрдХ рдХреЗ рдмрд╛рдж рддреАрд╕рд░рд╛ рдЯреЛрдХрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рддреАрди рдЯреЛрдХрдиреЛрдВ рдХреЛ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЕрдВрддрд┐рдо рдПрдХ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рд╣реЛрдЧреАред рдпрджрд┐ рдпрд╣ рдЦреЛрдЬрд╛ рдирд╣реАрдВ рдЧрдпрд╛ рд╣реИ, рддреЛ рд╕рднреА рдЯреЛрдХрди рдХреЛ рдореВрд▓ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ unget_token () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реМрдЯрд╛рдПрдВ

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, HTML :: TokeParser рдореЗрдВ, рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк рдЯреЛрдХрди рдФрд░ unget_token () рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/In163567/


All Articles