[SP-pm] Retirar conteúdo de Tabela

Andre Carneiro andregarciacarneiro at gmail.com
Wed Jan 21 03:01:31 PST 2009


Tem um problema que é o seguinte. O módulo pode matar o programa com die, se
você fizer algo do tipo

<code>
$tree->look_down(_tag => 'a')->attr('href');
</code>

Isso pode gerar um 'die', se o objeto $tree estiver 'unblessed'. Resumindo,
você deve ser explícito e ter sempre certeza que existe alguma coisa nos
teus objeto, de preferência um objeto 'HTML::Element'.. ;)

Algo assim:

<code>
use strict;
use HTML::TreeBuider;
use WWW::Mechanize;

my $mech           = WWW::Mechanize->new();
$mech->get('some_url');
if($mech->success){
               if(my $tree = HTML::TreeBuilder->new_from_content($string);){
                            if(my $url = $tree->look_down(_tag => 'a')){
                                           $url = $url->attr('href');
                            }
              }
}
else{
#trate o erro aqui.
}

</code>

Repare que para os 'ifs' internos eu não abri espaço para tratar erros. Por
que? Simplesmente porque não se trata de um erro realmente. Como designers
quase sempre pisam na bola com a questão de estrutura dos HTMLs, você
precisa se certificar que o seu programa não vai parar, só porque um mané
não sabe escrever HTML direito.


É claro que esse exemplo acima explica exatamente o que eu quero dizer, mas
vou dar um exemplo mais genérico. Considere o seguinte segmento de código
HTML abaixo:
<code>
<!-- um montão de coisa em HTML aqui.. -->
<tr>
     <td>produto1</td>
     <td>R$ 30,00</td>
 </tr>
<tr>
     <td>produto2
     <div>PRODUTO EM FALTA</div> <!-- acredite, eu já tive que lidar com
coisa bem pior que isso -->
    </td>
</tr>
<!-- mais um montão de coisa em HTML aqui -->
</code>


Percebe o problema? Se você tivesse um loop, onde você esperasse uma td que
não existe, você precisaria tratar isso, caso contrário o seu programa vai
parar.

Essas mudanças de padrão, HTMLs mal-estruturados, são mais chatos de tratar,
porque você precisa ficar 'caminhando' na árvore de objetos, isso supondo
que o HTML está consistente o suficiente(sem tags abertas perdidas e
porcarias do tipo), para você conseguir chegar onde você precisa.



Cheers!


2009/1/20 Blabos de Blebe <blabos at gmail.com>

> Desculpem ser chato, mas quando eu usei o HTML::TreeBuilder, precisei
> mudar para algo como:
>
> <code>
> my $tag = $tree_cidade->look_down(_tag => 'a');
> my $url = $tag ? $tag->attr('href') : '';
> </code>
>
> Porque se o look_down não encontrar  a tag <a> ele vai retornar undef.
> Daí tentar encadear uma chamada a attr() sobre o undef vai dar caca.
>
> Quando eu precisei fazer isso, haviam vários pontos problemáticos
> assim, os quais eram verbosos para tratar. Eu sempre queria fazer as
> chamadas encadeadas como o márcio fez, mas acabava tendo que separar
> uma a uma para o caso do look_down não encontrar nada.
>
> Existem soluções menos verbosas e mais elegantes?
>
> Abraços
>
> Wesley
>
>
>
> 2009/1/19 Daniel de Oliveira Mantovani <
> daniel.oliveira.mantovani at gmail.com>:
> > Isso mesmo Márcio!
> >
> > 2009/1/19 Márcio Vitor <cromo.jml at gmail.com>
> >>
> >> Daniel, vou bicar feio mas acho que você tá querendo algo assim:
> >>
> >> my $url = $tree_cidade->look_down(_tag => 'a')->attr('href');
> >>
> >> Márcio Vitor
> >>
> >> 2009/1/18 Daniel de Oliveira Mantovani
> >> <daniel.oliveira.mantovani at gmail.com>
> >>>
> >>> Olá pessoal, o André me ensinou uma maneira muito divertida de retirar
> >>> conteúdo com HTML::TreeBuilder.
> >>>
> >>> Ele ensinou a pegar os atributos com attr(), por exemplo pegar o <a
> >>> href="http://pegar_isso_aqui.com"> usaria $a->attr('href').
> >>>
> >>> Desse jeito funciona perfeitamente:
> >>> <code>
> >>>   my @cidades = $tree_page->look_down(_tag => 'li');
> >>>   foreach my $cidade (@cidades) {
> >>>      my $html = $cidade->as_HTML;
> >>>      my $tree_cidade = HTML::TreeBuilder->new_from_content($html);
> >>>      $tree_cidade->look_down(_tag => 'a');
> >>>      $tree_cidade->as_HTML =~ m{href="(.+?)"};
> >>>      push(@estados,"$1/bairros") if $1 !~ m{cidade};
> >>> </code>
> >>>
> >>> Porém do jeito que seria o correto não funciona:
> >>>
> >>> <code>
> >>>   my @cidades = $tree_page->look_down(_tag => 'li');
> >>>   foreach my $cidade (@cidades) {
> >>>      my $html = $cidade->as_HTML;
> >>>      my $tree_cidade = HTML::TreeBuilder->new_from_content($html);
> >>>      $tree_cidade->look_down(_tag => 'a');
> >>>      my $url = $tree_cidade->attr('href');
> >>> 39 push(@estados,"$url/bairros") if $url !~ m{cidade};
> >>> </code>
> >>>
> >>> Da o seguinte erro:
> >>> <erro>
> >>> Use of uninitialized value $url in concatenation (.) or string at
> >>> vcvai-0.01.pl line 39.
> >>> </erro>
> >>>
> >>> Se eu tento dar um print "$url\n"; da o mesmo erro na linha do print.
> >>>
> >>> Tentei de várioas maneiras e nada!
> >>>
> >>> []'s
> >>>
> >>>
> >>>
> >>> 2008/11/28 Nelson Ferraz <nferraz at gmail.com>
> >>>>
> >>>> Muito boa explicacão, André.
> >>>>
> >>>> Que tal colocá-la no wiki, pra facilitar a nossa vida mais tarde?
> >>>> (Para nós e para outras pessoas :))
> >>>>
> >>>> Sugiro colocá-lo na forma de uma Receita:
> >>>>
> >>>> ---
> >>>>
> >>>>    Título: Como fazer parsing de HTML
> >>>>
> >>>>    Problema: você precisa extrair informacões de um arquivo HTML
> >>>>
> >>>>    Solucão: use HTML::TreeBuilder
> >>>>
> >>>>    Discussão: (explicacão acima)
> >>>>
> >>>> ---
> >>>>
> >>>> Você pode usar este link para publicar uma nova receita:
> >>>>
> >>>> - http://www.perl.org.br/bin/viewauth/Artigos/WebReceitaForm
> >>>>
> >>>> []s
> >>>>
> >>>> Nelson
> >>>>
> >>>> --
> >>>> Nelson Ferraz
> >>>>
> >>>> Free Software Foundation Associate Member #3203
> >>>> Projeto Software Livre Brasil (www.softwarelivre.org.br)
> >>>> Sociedade Perl do Brasil (www.perl.org.br)
> >>>> Rede Livre de Compartilhamento de Cultura Digital
> >>>> _______________________________________________
> >>>> SaoPaulo-pm mailing list
> >>>> SaoPaulo-pm at pm.org
> >>>> http://mail.pm.org/mailman/listinfo/saopaulo-pm
> >>>
> >>>
> >>>
> >>> --
> >>> http://mantovanihouse.blogspot.com/
> >>>
> >>> -------(\_------------_/)-----------
> >>> -------)--(----------)--(-----------
> >>> ------(----(---------)----)----------
> >>> -------)----(-------)----(-----------
> >>> -------(----(-------)----)-----------
> >>> --------\_-(\\.---.//)-_/------------
> >>> ----------\)' -8--8- '(/--------------
> >>> -----------/------------\---------------
> >>> ----------(--)--------(--)--------------
> >>> ------------(_c__c_)----------------
> >>> ----------------------------------------
> >>>
> >>> _______________________________________________
> >>> SaoPaulo-pm mailing list
> >>> SaoPaulo-pm at pm.org
> >>> http://mail.pm.org/mailman/listinfo/saopaulo-pm
> >>
> >>
> >> _______________________________________________
> >> SaoPaulo-pm mailing list
> >> SaoPaulo-pm at pm.org
> >> http://mail.pm.org/mailman/listinfo/saopaulo-pm
> >
> >
> >
> > --
> > http://mantovanihouse.blogspot.com/
> >
> > -------(\_------------_/)-----------
> > -------)--(----------)--(-----------
> > ------(----(---------)----)----------
> > -------)----(-------)----(-----------
> > -------(----(-------)----)-----------
> > --------\_-(\\.---.//)-_/------------
> > ----------\)' -8--8- '(/--------------
> > -----------/------------\---------------
> > ----------(--)--------(--)--------------
> > ------------(_c__c_)----------------
> > ----------------------------------------
> >
> > _______________________________________________
> > SaoPaulo-pm mailing list
> > SaoPaulo-pm at pm.org
> > http://mail.pm.org/mailman/listinfo/saopaulo-pm
> >
> _______________________________________________
> SaoPaulo-pm mailing list
> SaoPaulo-pm at pm.org
> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>



-- 
André Garcia Carneiro
Analista/Desenvolvedor Perl
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20090121/bf4cea1f/attachment-0001.html>


More information about the SaoPaulo-pm mailing list