Bom galera, particularmente quando comecei a aprender programação sempre me interessei na funcionalidade de um programa poder interagir/acessar um site, espero hoje demonstrar de forma "mastigada" como fazer um programa em perl extrair um conteúdo de um site e filtrar o resultado por determinado campo.
- Introdução:
Em perl existem os chamados módulos,que podem ser encontrados em
http://search.cpan.org/, os módulos servem para oferecer mais funcionalidades ao programa, existem os mais diversos módulos, desde de alterar a cor da letra à módulos mais complexos como algorítimos de hashs. Para nosso exemplo vamos usar o módulo
LWP::UserAgent, esse módulo será responsável por fazer as requisições ao site. Existem outros módulos que fazem isso, os mais famosos são o
LWP::UserAgent e o
WWW::Mechanize.
1- Começando:
Em nosso primeiro exemplo, vamos simplesmente acessar um site e imprimir na tela o conteúdo dele. Nesse exemplo vamos usar o módulo LWP::Simple, que funciona exatamente igual ao LWP:UserAgent, mas com a vantagem de ser mais simples, perfeito para nosso primeiro exemplo.
Código PHP:
#!/usr/bin/perl
use warnings; #Habilita a mostragem de possiveis erros no código.
use LWP::Simple; # Usa o módulo LWP::Simple.
$conteudo = get("http://www.forum-invaders.com.br/"); #Acessa o site e coloca na variavel $conteudo
printf "$conteudo"; #Imprime na tela o que foi obtido no site.
Fácil não?! E se precisássemos salvar esse conteúdo recebido em um arquivo? Com o LWP::Simple é simples(sic).
Código PHP:
#!/usr/bin/perl
use warnings; #Habilita a mostragem de possiveis erros no código.
use LWP::Simple; # Usa o modulo LWP::Simple.
$file = "./sitesalvo.txt"; #Local onde sera salvo o conteudo do site.
$conteudo = getstore(("http://www.forum-invaders.com.br/"), $file); #Salva o conteudo do site em $file e coloca o "HTTP Response code" em $conteudo.
if ($conteudo == 200 ){ #Se o http response code for 200 ele imprime a linha abaixo.
printf "Site obtido com sucesso.\n"; #Imprime na tela o que foi obtido no site.
}else{
printf "Falha\n"; #Se o resultado do http response for diferente de 200.
}
No exemplo acima não quer dizer necessariamente que você obteve o conteúdo que queria, apenas quer dizer que você conseguiu acessar o site e obter algum conteúdo(qualquer que seja ele). Mais sobre http response codes aqui.
2 - LWP:UserAgent:
Está na hora de usar o LWP::UserAgent, com ele temos mais funcionalidade e opções de controle de fluxo de informações, no exemplo agora vamos obter o conteúdo de um site usando mais opções, como Timeout, Proxy e obter um campo específico. Neste exemplo, o script entra no site http://www.forum-invaders.com.br e exibe na tela o último membro cadastrado.
Código PHP:
#!/usr/bin/perl
use warnings; #Habilita a mostragem de possiveis erros no código.
use LWP::UserAgent; # Usa o modulo LWP::UserAgent.
$ua = LWP::UserAgent->new(); #Cria um novo UserAgent.
$ua-> agent("Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4"); #Configura um agent.
$ua->timeout( 60 ); #Seta o tempo máximo de espera por uma resposta.
$ua->proxy('http', "http://219.145.93.110:8080"); #Habilita e configura o uso de um proxy.
$resp = $ua->get("http://www.forum-invaders.com.br/"); #Entra no site.
$conteudorecebido = $resp->content; #Coloca o conteúdo do site na variavel $conteudorecebido.
if ($conteudorecebido =~ /<p>Boas-vindas a <a href="(.*)">(.*)<\/a><\/p>/){ #regex explicada no forum.
printf "A última pessoa a se registrar no Forum invaders foi:$2\n"; #Imprime o segundo resultado que bate com o filtro da Regex.
}else{printf "Fail\n"; #Se não tiver algo que bata com a regex imprima Fail.
}
Para quem se complicou um pouco nesse código, vamos dar uma olhada nas linhas que se diferem dos exemplos anteriores:
$ua = LWP::UserAgent->new();
Nessa linha estamos criando um user agent, vamos entender esse user agent como um browser, que podemos configurar como se configurássemos nosso navegador, colocando proxy, cookies, etc.
$ua-> agent("Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4");
Nessa linha nos setamos o agent(essa linha é opcional), o agent é como o site reconhece o browser visitante, nesse caso o site "pensa" que quem esta visitando ele é um usuário com windows usando o firefox.
$ua->proxy('http', "http://219.145.93.110:8080");
Configura o proxy, nesse exemplo eu usei um proxy que não precisa de senha, mas se for usar em um local que peça senha é só trocar por esse parâmetro abaixo:
http://usuario:senha@ip:porta
if ($conteudorecebido =~ /<p>Boas-vindas a <a href="(.*)">(.*)<\/a><\/p>/){
printf "A última pessoa a se registrar no Forum invaders foi:$2\n";
Essa linha é a responsável por trazer justamente a última pessoa registrada do fórum, mas como? Para entender melhor devemos nos perguntar, "O que eu quero encontrar está entre quais parâmetros?" Nesse caso está em
<p>Boas-vindas a <a href="member.php/idusuário">usuario</a></p>
Sabemos que idusuário e usuário são os campos dinâmicos, então usamos a regex (.*) para trazer justamente qualquer coisa que estiver nesse local. A expressão regular(regex) vai filtrar de todo o conteúdo do site por justamente o que está em (.*). Ai você se pergunta, sim mas onde é que o "$1"entra nessa história? Bom, o $1,$2,$3, são as variáveis que trazem os termos que bateram com a expressão regular e que estão dentro de (.*), eu usei $2 porque eu queria o usuário, o $1 foi usado no campo do idusuário.
3 - Usando Formulários(método POST) - FIM
O Post é geralmente usado em formulários, nosso programa vai preencher um formulário, apertar o botão e obter o resultado na página seguinte. Lets go!
Neste exemplo vamos entrar no site
http://md5encryption.com/ que é um site que transforma strings de texto livre em um hash md5, o programa vai entrar, preencher o formulário com alguma palavra, apertar o botão e imprimir na tela o resultado da encriptação.
Código PHP:
#!/usr/bin/perl
use warnings; #Habilita a mostragem de possiveis erros no código.
use LWP::UserAgent; # Usa o modulo LWP::Simple.
printf "Qual a string que deseja encriptar?\n";
$string=<STDIN>; #Captura o que for digitado e seta a variavel $string.
chomp($string); # Retira o carriage.
$ua = LWP::UserAgent->new(); #Cria um novo UserAgent.
$ua-> agent("Invaders Browser"); #Configura um agent.
$ua->timeout( 60 );
$resp = $ua->post("http://md5encryption.com/", #Explicação no post do fórum.
{ "word" => "$string", #Explicação no post do fórum
"submit" => "Encrypt It!" }); #Explicação no post do fórum.
$conteudorecebido = $resp->content; #Coloca o conteúdo do site na
if ($conteudorecebido =~ /Md5 Hash:<\/b> (.*)<\/font>/){ #regex
printf "STRING MD5\n$string $1\n"; #Imprime o resultado que bate com o filtro da Regex.
}else{
printf "Fail\n";
} #Se não tiver algo que bata com a regex imprima Fail.}
Para entender melhor vamos dar uma olhada no código fonte do site que usamos(md5encryption.com) e nos focarmos no formulário deles:
<form action="" method="post" class="theform"><input type="text" name="word" size="60">
<input type="submit" name="submit" value="Encrypt It!">
Agora vamos para as linhas diferentes de nosso programa:
$resp = $ua->post("http://md5encryption.com/",
{ "word" => "$string",
"submit" => "Encrypt It!" });
Em vez de GET usamos o POST, já que é o método usado no formulário,
"word" equivale ao nome do formulário do site, "
Submit" equivale ao
name do botão e
"Encrypt it" equivale ao
value.
if ($conteudorecebido =~ /Md5 Hash:<\/b> (.*)<\/font>/){ #regexMesmo caso do exemplo passado, vendo no código da página eu descobri que os resultados saem entre:
Md5 Hash:</b> 21232f297a57a5a743894a0e4a801fc3</font>
então foi só colocar a regex com (.*) no campo dinâmico e trazer o resultado da variável usando $1.
Bom Jovens, espero que tenha ficado fácil de entender, vale lembrar que um dos motes do perl é "sempre vai haver uma outra forma de se fazer", então todos os exemplos que eu fiz, podem ser modificados, aumentando o desempenho, encurtando sintaxes, etc, mas gostaria de lembrar que o foco aqui foi facilitar o entendimento, ai a partir dai o leitor ter capacidade de começar a optimizar o código.
Abraços.