Tem um problema que é o seguinte. O módulo pode matar o programa com die, se você fizer algo do tipo<br><br><code><br>$tree->look_down(_tag => 'a')->attr('href');<br></code><br><br>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'.. ;)<br>
<br>Algo assim:<br><br><code><br>use strict;<br>use HTML::TreeBuider;<br>use WWW::Mechanize;<br><br>my $mech = WWW::Mechanize->new();<br>$mech->get('some_url');<br>if($mech->success){<br> if(my $tree = HTML::TreeBuilder->new_from_content($string);){<br>
if(my $url = $tree->look_down(_tag => 'a')){<br> $url = $url->attr('href');<br> }<br> }<br>
}<br>else{<br>#trate o erro aqui.<br>}<br><br></code><br><br>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. <br>
<br><br>É 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:<br><code><br><!-- um montão de coisa em HTML aqui.. --><br>
<tr><br> <td>produto1</td><br> <td>R$ 30,00</td><br> </tr><br><tr><br> <td>produto2<br> <div>PRODUTO EM FALTA</div> <!-- acredite, eu já tive que lidar com coisa bem pior que isso --><br>
</td><br></tr><br><!-- mais um montão de coisa em HTML aqui --><br></code><br><br><br>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.<br>
<br>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.<br>
<br><br><br>Cheers!<br><br><br><div class="gmail_quote">2009/1/20 Blabos de Blebe <span dir="ltr"><<a href="mailto:blabos@gmail.com">blabos@gmail.com</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Desculpem ser chato, mas quando eu usei o HTML::TreeBuilder, precisei<br>
mudar para algo como:<br>
<br>
<code><br>
my $tag = $tree_cidade->look_down(_tag => 'a');<br>
my $url = $tag ? $tag->attr('href') : '';<br>
</code><br>
<br>
Porque se o look_down não encontrar a tag <a> ele vai retornar undef.<br>
Daí tentar encadear uma chamada a attr() sobre o undef vai dar caca.<br>
<br>
Quando eu precisei fazer isso, haviam vários pontos problemáticos<br>
assim, os quais eram verbosos para tratar. Eu sempre queria fazer as<br>
chamadas encadeadas como o márcio fez, mas acabava tendo que separar<br>
uma a uma para o caso do look_down não encontrar nada.<br>
<br>
Existem soluções menos verbosas e mais elegantes?<br>
<br>
Abraços<br>
<br>
Wesley<br>
<br>
<br>
<br>
2009/1/19 Daniel de Oliveira Mantovani <<a href="mailto:daniel.oliveira.mantovani@gmail.com">daniel.oliveira.mantovani@gmail.com</a>>:<br>
<div><div></div><div class="Wj3C7c">> Isso mesmo Márcio!<br>
><br>
> 2009/1/19 Márcio Vitor <<a href="mailto:cromo.jml@gmail.com">cromo.jml@gmail.com</a>><br>
>><br>
>> Daniel, vou bicar feio mas acho que você tá querendo algo assim:<br>
>><br>
>> my $url = $tree_cidade->look_down(_tag => 'a')->attr('href');<br>
>><br>
>> Márcio Vitor<br>
>><br>
>> 2009/1/18 Daniel de Oliveira Mantovani<br>
>> <<a href="mailto:daniel.oliveira.mantovani@gmail.com">daniel.oliveira.mantovani@gmail.com</a>><br>
>>><br>
>>> Olá pessoal, o André me ensinou uma maneira muito divertida de retirar<br>
>>> conteúdo com HTML::TreeBuilder.<br>
>>><br>
>>> Ele ensinou a pegar os atributos com attr(), por exemplo pegar o <a<br>
>>> href="<a href="http://pegar_isso_aqui.com" target="_blank">http://pegar_isso_aqui.com</a>"> usaria $a->attr('href').<br>
>>><br>
>>> Desse jeito funciona perfeitamente:<br>
>>> <code><br>
>>> my @cidades = $tree_page->look_down(_tag => 'li');<br>
>>> foreach my $cidade (@cidades) {<br>
>>> my $html = $cidade->as_HTML;<br>
>>> my $tree_cidade = HTML::TreeBuilder->new_from_content($html);<br>
>>> $tree_cidade->look_down(_tag => 'a');<br>
>>> $tree_cidade->as_HTML =~ m{href="(.+?)"};<br>
>>> push(@estados,"$1/bairros") if $1 !~ m{cidade};<br>
>>> </code><br>
>>><br>
>>> Porém do jeito que seria o correto não funciona:<br>
>>><br>
>>> <code><br>
>>> my @cidades = $tree_page->look_down(_tag => 'li');<br>
>>> foreach my $cidade (@cidades) {<br>
>>> my $html = $cidade->as_HTML;<br>
>>> my $tree_cidade = HTML::TreeBuilder->new_from_content($html);<br>
>>> $tree_cidade->look_down(_tag => 'a');<br>
>>> my $url = $tree_cidade->attr('href');<br>
>>> 39 push(@estados,"$url/bairros") if $url !~ m{cidade};<br>
>>> </code><br>
>>><br>
>>> Da o seguinte erro:<br>
>>> <erro><br>
>>> Use of uninitialized value $url in concatenation (.) or string at<br>
>>> <a href="http://vcvai-0.01.pl" target="_blank">vcvai-0.01.pl</a> line 39.<br>
>>> </erro><br>
>>><br>
>>> Se eu tento dar um print "$url\n"; da o mesmo erro na linha do print.<br>
>>><br>
>>> Tentei de várioas maneiras e nada!<br>
>>><br>
>>> []'s<br>
>>><br>
>>><br>
>>><br>
>>> 2008/11/28 Nelson Ferraz <<a href="mailto:nferraz@gmail.com">nferraz@gmail.com</a>><br>
>>>><br>
>>>> Muito boa explicacão, André.<br>
>>>><br>
>>>> Que tal colocá-la no wiki, pra facilitar a nossa vida mais tarde?<br>
>>>> (Para nós e para outras pessoas :))<br>
>>>><br>
>>>> Sugiro colocá-lo na forma de uma Receita:<br>
>>>><br>
>>>> ---<br>
>>>><br>
>>>> Título: Como fazer parsing de HTML<br>
>>>><br>
>>>> Problema: você precisa extrair informacões de um arquivo HTML<br>
>>>><br>
>>>> Solucão: use HTML::TreeBuilder<br>
>>>><br>
>>>> Discussão: (explicacão acima)<br>
>>>><br>
>>>> ---<br>
>>>><br>
>>>> Você pode usar este link para publicar uma nova receita:<br>
>>>><br>
>>>> - <a href="http://www.perl.org.br/bin/viewauth/Artigos/WebReceitaForm" target="_blank">http://www.perl.org.br/bin/viewauth/Artigos/WebReceitaForm</a><br>
>>>><br>
>>>> []s<br>
>>>><br>
>>>> Nelson<br>
>>>><br>
>>>> --<br>
>>>> Nelson Ferraz<br>
>>>><br>
>>>> Free Software Foundation Associate Member #3203<br>
>>>> Projeto Software Livre Brasil (<a href="http://www.softwarelivre.org.br" target="_blank">www.softwarelivre.org.br</a>)<br>
>>>> Sociedade Perl do Brasil (<a href="http://www.perl.org.br" target="_blank">www.perl.org.br</a>)<br>
>>>> Rede Livre de Compartilhamento de Cultura Digital<br>
>>>> _______________________________________________<br>
>>>> SaoPaulo-pm mailing list<br>
>>>> <a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
>>>> <a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
>>><br>
>>><br>
>>><br>
>>> --<br>
>>> <a href="http://mantovanihouse.blogspot.com/" target="_blank">http://mantovanihouse.blogspot.com/</a><br>
>>><br>
>>> -------(\_------------_/)-----------<br>
>>> -------)--(----------)--(-----------<br>
>>> ------(----(---------)----)----------<br>
>>> -------)----(-------)----(-----------<br>
>>> -------(----(-------)----)-----------<br>
>>> --------\_-(\\.---.//)-_/------------<br>
>>> ----------\)' -8--8- '(/--------------<br>
>>> -----------/------------\---------------<br>
>>> ----------(--)--------(--)--------------<br>
>>> ------------(_c__c_)----------------<br>
>>> ----------------------------------------<br>
>>><br>
>>> _______________________________________________<br>
>>> SaoPaulo-pm mailing list<br>
>>> <a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
>>> <a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
>><br>
>><br>
>> _______________________________________________<br>
>> SaoPaulo-pm mailing list<br>
>> <a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
>> <a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
><br>
><br>
><br>
> --<br>
> <a href="http://mantovanihouse.blogspot.com/" target="_blank">http://mantovanihouse.blogspot.com/</a><br>
><br>
> -------(\_------------_/)-----------<br>
> -------)--(----------)--(-----------<br>
> ------(----(---------)----)----------<br>
> -------)----(-------)----(-----------<br>
> -------(----(-------)----)-----------<br>
> --------\_-(\\.---.//)-_/------------<br>
> ----------\)' -8--8- '(/--------------<br>
> -----------/------------\---------------<br>
> ----------(--)--------(--)--------------<br>
> ------------(_c__c_)----------------<br>
> ----------------------------------------<br>
><br>
> _______________________________________________<br>
> SaoPaulo-pm mailing list<br>
> <a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
> <a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
><br>
_______________________________________________<br>
SaoPaulo-pm mailing list<br>
<a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>André Garcia Carneiro<br>Analista/Desenvolvedor Perl<br><br>