Logotipo desenvolvimento para web

Como pegar parte do conteúdo (dados) de outro site com PHP

Pegar parte do conteúdo de outro site foi a tarefa que tive que fazer. Pensei que seria bem fácil, mas as coisas não saíram exatamente como eu planejava… Felizmente, consegui! Aprenda, você, também, como coletar informações de outros sites na internet.

A missão: pegar parte do conteúdo de um site

Hoje, no trabalho, tive a missão de “puxar” alguns dados de um site para “enxertar” num trecho de um web site que estou ajudando a desenvolver. Quando a tarefa me foi passada, logo lembrei de uma ocasião em que um amigo fez a mesma coisa (e, na época, ele me explicou, mais ou menos, com o fez). Pensei que seria muito fácil realizar a tarefa, mas, na hora, “lembrei” que não sou tão bom quanto o Gevã… rsrs

A solução: funções nativas do PHP e expressões regulares

Passei para pesquisas na web, procurando desesperadamente material de referência sobre expressões regulares (que, como verão, é um dos pilares para se conseguir pegar parte do conteúdo de outro site). Procura daqui, procura de lá, até bate-papo com o Gevã rolou para eu tentar entender melhor as tais expressões regulares. Até que, utilizando um pouco de “gambiarra”, consegui realizar meu objetivo.

A primeira coisa a se fazer, é pegar o conteúdo da página inteira que se quer “manipular”. Para tal, usa-se, por exemplo, a função file_get_contents(). Jogando o conteúdo do site numa variável, ficaria assim (vou fazer o exemplo com o mesmo site que tive que mexer):

1
$url = file_get_contents('http://www.bcb.gov.br/');

Pronto, agora a variável $url contém, em string, todo o conteúdo da página inicial do BCB.

Expressões regulares

Até aqui foi fácil; o difícil foi pegar somente o trecho da página que eu queria… Para isso, é preciso usar expressões regulares!

Caso você não saiba o que são expressões regulares, aí vai uma sucinta (e incompleta…) explicação de o que são expressões regulares, da Wikipédia:

Uma expressão regular, na Informática, define um padrão a ser usado para procurar ou substituir palavras ou grupos de palavras. É um meio preciso de se fazer buscas de determinadas porções de texto.

Com as expressões regulares é possível identificar trechos de palavras ou grupos de palavras que correspondem (“match“) a um determinado padrão (“pattern“), que é “regular”.

O PHP tem várias funções nativas para trabalhar com expressões regulares. Basta saber para o que cada uma serve e usar da meneira correta.

Bem, o próximo passo para resolução do problema é identificar o padrão que se quer extrair do site. No caso, eu precisei de uma tabela com algumas taxas cambiais (encontra-se à direita, no site do BCB). Observando o código fonte, vi que as informações estão em uma tabela (abordagem semanticamente correta!); além disso, esta tabela está envolta entre os comentários HTML “<!- – INICIO INDICADORES – ->” e “<!- – FIMINDICADORES – ->”. Isso é uma coisa boa, já que facilita bastante a “identificação do padrão”.

Explicando melhor: o padrão procurado, no caso, é tudo o que está entre os comentários HTML “<!- – INICIO INDICADORES – ->” e “<!- – FIMINDICADORES – ->”. Toda a tabela está aí, para a minha felicidade! :-)

Então, tudo o que é preciso fazer é utilizar uma função PHP (para o caso, escolhi a preg_match_all()) para procurar uma expressão regular dentro da variável $url, que contém toda a primeira página do site em que está a tabela.

Depois de muito tempo testando vááárias expressões regulares, cheguei à conclusão que faria uma pequena mutreta. Mas, antes, deixe-me mostrar como está o código até agora.

1
2
$url = file_get_contents('http://www.bcb.gov.br/');
preg_match_all('/ORES--&gt;(.+)<!--/s', $url, $conteudo);

Explicando: o primeiro argumento da função, é o padrão que quero procurar; o segundo, é onde vou procurar; o terceiro, guarda em um array todas as ocorrências da expressão procurada. Para a maioria dos casos, talvez já estivesse bom, por aqui; entretanto, no problema que tive, ainda é preciso mais algumas linhas de código.

No momento, a variável $conteudo contém um array com as ocorrências encontradas. Usando um print_r(), descobri em qual posição, exatamente, o que eu procurava estava: $conteudo[0][0].

Fazendo uma “mutreta”

Para fazer a tal “mutreta”, jogo o conteúdo desta posição da matriz para uma outra variável (para facilitar a manipulação).

1
2
3
$url = file_get_contents('http://www.bcb.gov.br/');
preg_match_all('/ORES-->(.+)<!--/s', $url, $conteudo);
$exibir = $conteudo[0][0];

Havia trechos do que me foi retornado (ou seja, da tabela com as taxas cambiais) que eu não queria que aparecessem no site (como alguns links). Então, resolvi retirá-los através da função str_replace(), que substitui trechos de strings. É possível, como argumento, passar um array. Então, por enquanto e quase no fim, o código está assim:

1
2
3
4
5
$url = file_get_contents('http://www.bcb.gov.br/');
preg_match_all('/ORES-->(.+)<!--/s', $url, $conteudo);
$exibir = $conteudo[0][0];
$retirar = array('mais moedas','atas Copom','mais detalhes','ORES-->','<!--');
$exibir = str_replace($retirar, '', $exibir);

Ou seja: sempre que aparecer alguns dos itens do array $retirar em $exibir, será substituído por “” (nada…). Perceba que os últimos dois elementos do array são “poluições” desnecessárias, que vieram devido à minha preguiça de fazer uma expressão regular mais elaborada. :-)

Finalizando…

Depois disso, basta mandar exibir na tela o que “sobrou” do conteúdo retira da página inicial do site do BCB.

1
2
3
4
5
6
$url = file_get_contents('http://www.bcb.gov.br/');
preg_match_all('/ORES-->(.+)<!--/s', $url, $conteudo);
$exibir = $conteudo[0][0]</span>;
$retirar = array('mais moedas','atas Copom','mais detalhes','ORES-->','<!--');
$exibir = str_replace($retirar, '', $exibir);
echo $exibir;

E se o servidor não permite a função file_get_contents() ?

Há muitos servidores que, por motivos diversos (principalmente "segurança"), não permitem que se utilize a função file_get_contents(). Para esses casos, é possível colocar numa variável alguma página externa utilizando o seguinte código (depois você procura as explicações no manual oficial do PHP):

1
2
3
4
5
6
7
$ch = curl_init();
$timeout = 0;
curl_setopt($ch, CURLOPT_URL, 'O_SITE_QUE_VOCE_QUER');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$conteudo = curl_exec ($ch);
curl_close($ch);

Então, o conteúdo da página "O_SITE_QUE_VOCE_QUER" estará na variável $conteudo.

Conclusão

Então, pessoal, para se retirar uma parte do conteúdo de um web site (utilizando PHP), os passos são:

  • Saber em qual página está o conteúdo que se precisa;
  • Jogar o conteúdo do site em uma variável;
  • Extrair o trecho que se quer utilizando expressões regulares;
  • Se preciso, cortar mais algumas coisas do resultado da ER;
  • Exibir em tela o resultado final.

O grande pulo do gato, neste caso, é saber mexer com expressões regulares; coisa que, sinto informar, só se aprende fazendo! E fazendo muito! Leia as referências no fim deste artigo e procure na internet mais material a respeito.

Uma outra coisa importante é o seguinte: tenha sempre em mente que, como você está pegando o conteúdo de um site, caso este altere sua estrutura, muito provavelmente será preciso alterar a expressão regular, também.

Fique ciente de uma coisa: se você, desenvolvedor web, ainda não precisou usar expressões regulares, pode ter certeza de que sua hora vai chegar!

Referências Nacionais

Expressões Regulares - Guia de Consulta Rápida

Este é o guia de Aurélio Marinho Jargas, excelente para se aprender expressões regulares e para se consultar nos momentos de aperto!

Expressões Regulares no PHP

Artigo do Viva o Linux, de Marcelo Santos Araujo, com uma introdução sobre expressões regulares.

Referências Internacionais

Regular-Expressions.info

Site especialmente dedicado às expressões regulares.

Regular Expression Library

Biblioteca virtual de expressões regulares.

RegExr

Para testar expressões regulares em tempo real!

Todo desenvolvedor web deve ler

Use a cabeça: HTML com CSS e XHTML PHP e MySQL: Desenvolvimento Web Internet e World Wide Web: Como Programar Criando páginas web com CSS Usabilidade na web Design para a internet Não me faça pensar jQuery: A Biblioteca do Programador JavaScript Ajax com jQuery: Requisições AJAX com a Simplicidade de jQuery

30 comentários em "Como pegar parte do conteúdo (dados) de outro site com PHP"

  1. Gevã Schaefer (30/03/2008)  

    Excelente, sr.Tárcio! Você pegou um limão e fez uma limonada. O artigo ficou muito bom, parabéns!

  2. Tárcio Zemel (31/03/2008)  

    Muito obrigado, Seu Gevã!

    50% é crédito seu! =D

    Abraços!

  3. Rafael Eduardo Kassner (03/04/2008)  

    Vale lembrar que com a utilização de XHTML na estrutura das páginas isso é desnecessário, uma vez que a extração dos dados pode ser feita exatamente da mesma maneira que se extrai os dados de um XML.

  4. Tárcio Zemel (04/04/2008)  

    @ Rafael Eduardo Kassner

    Oi, Rafael, tudo bem?!

    Muito interessante isso que você falou! Poderia dar um exemplo para podermos aprender?

    Abraços!

  5. Juliano (06/05/2008)  

    Valeu a mão!

    Quem quiser se aprofundar, vai aí um ótimo link sobre ER:
    http://guia-er.sourceforge.net/

    Pra mim foi muito útil!

  6. Tárcio Zemel (24/06/2008)  

    @ Juliano
    Obrigado por relembrar o site do Aurélio. Melhor, mesmo, é comprar o livrinho de referência que ele fez mas, para consultas online, é muito bom!

    Obrigado pela visita!

  7. Felipe Conde (30/09/2008)  

    Muito bom msm o tuto.
    consegui fazer direitinho!

    agora tem uma coisa, eu n to conseguindo colocar o conteudo salvo na minha página.
    como que eu falo isso?

    eu estou simplesmente colcando o codigo php na minha index.html
    estou errado? qual a maneira certa de fazer isso?!

  8. Tárcio Zemel (01/10/2008)  

    @ Felipe Conde
    Na verdade, Felipe, não há “conteúdo salvo”; como o script pega o conteúdo de outro site, ele é inserido dinamicamente, então, ele se altera caso o conteúdo do “site alvo” seja alterado.

    Quanto ao local onde será exibido, você mesmo define. Seguindo o exemplo do artigo, caso esteja usando com file_get_contents(), o conteúdo fica na variável $exibir; caso esteja usando curl(), então é em $conteudo.

  9. Gabriel (02/10/2008)  

    Show de bola o tuto.

    Fui tentar fazer uma adaptação para a cotação agropecuaria (http://www.ruralnetwork.com.br/commodities2_canal_boi.asp), mas da o seguinte erro: failed to open stream: Invalid argument.

    Poderia me da uma ajudinha?

    Segue o codigo:
    $url = file_get_contents (“https://www.ruralnetwork.com.br/commodities2_canal_boi.asp”);
    preg_match_all(‘/data:(.+)/’, $url, $cotacao);

    print_r ($cotacao);

    Vlw´s

  10. Tárcio Zemel (02/10/2008)  

    @ Gabriel
    Gabriel, provavelmente o fato de ser “https” deve influenciar nisso. Dê uma olhadinha nesta discussão para começar a busca pela informação! ;-)

    Boa sorte e obrigado por comentar!

  11. Rodrigo (17/11/2008)  

    Olá Tárcio, tudo tranquilo?

    Então, muito bom o exemplo. Agora estou com uma dúvida:
    Tenho um conteúdo que é apresentado da seguinte maneira:

    div
    ContentTemplate>
    class=”preformatted”
    pre
    br
    O texto aqui dentro interessa, texto aqui dentro interessa texto aqui dentro interessa texto aqui dentro interessa texto aqui dentro interessa texto aqui dentro interessa texto aqui dentro interessa .
    br
    ESTA LINHA NAO INTERESSA ESTA LINHA NAO INTERESSA
    ESTA LINHA NAO INTERESSA ESTA LINHA NAO INTERESSA
    pre
    div

    É possível pegar apenas o conteúdo entre as tags br ??? Lembrando que tenho outras tags pelo corpo da página.

    Utilizei até o momento o código :

    $url = file_get_contents(‘http://meusite.com.br’);
    preg_match_all(‘/ContentTemplate(.+)/s’, $url, $conteudo);
    $exibir = $conteudo[0][0];
    $retirar = array(‘Filtro1, Filtro2, Filtro3′);
    $exibir = str_replace($retirar, ”, $exibir);
    echo $exibir;

  12. Tárcio Zemel (18/11/2008)  

    @ Rodrigo
    É possível, sim, Rodrigo. Basta utilizar a mesma “máscara” para pegar tudo que está entre os elementos que você quer. Ficaria algo como:

    preg_match_all(‘/br(.+)br/s’, $url, $conteudo);

    Sendo que este “br” é a tag de quebra de linha – só que não deu pra colocar, se não ele efetivamente quebraria a linha! ;-)

  13. Charles (13/01/2009)  

    Em vendo seu post primeiro meus parabens..
    Criei seu exemplo e gostei mas fiquei curioso pra saber como o pessoal faz pra pegar vi num site http://blogblogs.com.br o pessoal cadastra nele e colo o link e o site faz uma cópia do conteudo… mas somente do texto ( acho que o pessoal chama de POST ). Como eles conseguem tal façanha..?

  14. Sara (21/01/2009)  

    Estou a tentar tirar os cinemas do site http://cinema.sapo.pt/em-cartaz/distrito/aveiro/concelho/aveiro/pagina1 e não sei como ei-de ligar a base de dados para fazer a inserção dos conteudos retirados. Será que me poderiam ajudar…urgentemente…………..

    Alguem viu o meu post e sabe qual a solução?

  15. Tárcio Zemel (26/01/2009)  

    @ Charles
    Seguindo o “foco” deste post, poderia ser, por exemplo, pegar tudo o que está entre as tags de parágrafo (“p”) ou eles fazem uma série de IFs para buscar nomes de DIVs que normalmente têm conteúdos.

    @ Gustavo Henrique
    Não sei, Gustavo! Pelo seu comentário parece que havia algo anteriormente, mesmo, mas, sinceramente, também não sei! :-(

    @ Sara
    É seguindo o mesmo princípio que foi mostrado neste artigo: você analise o código-fonte para saber qual trecho quer “retirar” e utiliza as expressões regulares. Abraços!

  16. yuso (02/02/2009)  

    estou com uma pequena duvida.
    como pegar os outros links da pagina e algumas coisas que voce esta retirando o conteudo ?
    eu tentei usar file_get_contents outra vez so que aparece o primeiro link netão so conseigo pegar o conteudo do primeiro link será que é possivel fazer isso o que eu estou dizendo ? obrigado

  17. Lucas Moreira de Souza (03/05/2009)  

    Cara, parabéns pelo ÓTIMO conteúdo disponível neste tutorial!
    O primeiro teste que vou fazer para buscar conteúdo é aqui no seu site. Rsrs

    Pode ficar tranquilo que seu nome estará lá.

    Parabéns!!

  18. Tárcio Zemel (04/05/2009)  

    @ yuso
    Não entendi muito bem… Poderia explicar melhor?

    @ Lucas Moreira de Souza
    Opa! Que bom que gostou, Lucas! Tomara que seus testes deem certo! Entrei no seu site e gostei bastante! Design muito bom!

    Abraços!

  19. viConcursos (10/08/2009)  

    Cara, parabéns pelo ÓTIMO conteúdo disponível neste tutorial!
    vlw mesmo..

  20. Danilo Oliveira (24/09/2009)  

    Tentei fazer a mesma coisa que voce fez, mas usando javascript.. A ideia era colocar o tal site nu iframe e pegar as infos de la… Mas por umas questoes de seguranca, o js nao consegue pegar!
    Dai tentei fazer em php, num script bastante semelhante ao seu.. Mas me deparei com um pequeno problema. No meu caso, a informacao que quero extrair eh de um site de jogo… que preciso logar para pegar a tal informacao. No js nao teria problema, pois ao logar 1x, quando abro novamente a pagina ele ja ta logado… mas usando php nao!
    Pergunta:
    Tem como eu passar meu login e senha via php para o site q eu quero extrair os dados?
    Vlws
    Abracos

    E parabens pelo trabalho! pesquisei muito na net para tentar resolver esse problema! e de todas dicas/tutoriais/informacoes que achei, definitivamente, o seu site foi o MAIS completo! organizado e didatico! Parabens mesmo!

  21. Tárcio Zemel (25/09/2009)  

    @ Danilo Oliveira
    Obrigado pela força, Danilo! Que bom que você achou o artigo útil!

    Para o seu problema realmente fica complicado, já que você tem que logar para pegar a informação. Você logar e depois pegar a informação funciona, mas imagina os visitantes que não teriam como fazer isso… De repente você encontra essas informações em outro site que não seja protegido por senha.

    Abraços!

  22. Eusebio (19/10/2009)  

    Caro Tarcio

    Meus parabens pelo script… bem bolado e funcionou direitinho.
    So tenho uma duvida que creio ser facil para o senhor me auxiliar

    Capturei alguns dados que precisava de um site, onde usei:
    $url = file_get_contents(‘http://www.xxx.com.br/Telas.asp?Num=’ . $numero . ‘&acao=e’);
    Sendo que fiz um while para gerar varios $numero..
    Deu certo pois a pagina a ser capturada tinha um FORM GET…

    Mas agora me deparei com um site que usa um FORM POST
    Como deverei usar o $url??
    $url = file_get_contents(‘http://www.yyy.com.br/Telas.asp?’);
    Minha duvida é:Onde insiro o campo , pois nao da certo usar o $url com o numero direto no link.

    Sera que me fiz entender?? Seria possivel me auxiliar??

    Desde ja agradeço

    Eusebio

  23. Tárcio Zemel (21/10/2009)  

    @ Eusebio
    Dê uma olhadinha na função “file_post_contents”.

    Eu nunca a experimentei, mas acho que foi isso que você perguntou, não é? :-)

  24. Deivid (13/12/2009)  

    E no caso pra pegar links ???

    exemplo: pegar links da pagina B.

    existe alguma funcao especifica ou tem que adaptar esta ai ?

  25. Deivid (14/12/2009)  

    pra ser mais especifico…

    tem a pagina A e a B.

    quando entrar na pagina A, ela vai ler os links que tem na B, e salvar nos dados da A.

    e possivel ?

  26. Tárcio Zemel (15/12/2009)  

    @ Deivid
    Seria usando o que está explicado, mesmo, Deivid. Utilize preg_match_all() para pegar os links e faça o que for necessário depois.

  27. Aramis (19/01/2010)  

    Olá pessoal,
    tenho um problema e acho que vcs podem me ajudar ….

    Bom, gostaria de “imprimir ou passar” o conteúdo dentro de um DIV de uma página para outra página.

    Exemplo:

    Pagina1.html

    Texto em html

    Gostaria de fazer um botão de impressão onde abre uma outra página (Página2.html) com o conteudo da DIV “divNoticiaConteudo”, onde irei colocar mais alguns dados de cabeçalho.

  28. Tárcio Zemel (22/01/2010)  

    @ Aramis
    Se precisar somente server-side, aqui está a base para fazer, mas você precisará aprofundar nas expressões regulares. Se não for estritamente necessário, então você vai conseguir isso usando o método load() do jQuery.

  29. Jorge (17/02/2010)  

    preciso fazer um esquema praticamente igual a esse porem tem algumas coisas a mais, pode me passar seu msn para nós conversar

Deixe um comentário

artigos comentários e-mail ?
Siga-me no twitter!