phpQuery (web scraping) – Já imaginou selecionar elementos de um outro site com php utilizando a semântica de elementos como do css?
Com esse tutorial você irá capturar elementos de outro site como se estive-se um CSS ou jQquery.
Você conhece o CURL, Já utilizou inúmeras vezes para captura de por exemplo valor atualizado do Dolar ou para captura de endereço por CEP, correto? Então já se imaginou capturarando textos, imagens, palavras de outro site utilizando a semântica de seleção de objetos com o do CSS?
Deixa eu resumir com uma imagem
Entendeu? Não?? Deixa eu explicar melhor então!
phpQuery é uma classe criada para utilizar métodos DOM para captura dos elementos, assim como fazemos com o jQuery e o CSS, por exemplo
Para selecionar todos os elementos da classe de um html assim <label class=”classe_imagens”> basta colocar .classe_imagens, assim irá capturar todos os elementos dessa classe.
Para selecionar o elemento de uma div que contenha um ID, exemplo: <li id=”pegar_valor”>123</li> basta colocar #pegar_valor, assim irá capturar o valor desse ID que seria 123.
Primeiramente irei exibir uma captura simples sem usar o CURL. Antes de começar é necessário baixar a classe phpQuery, ela pode ser baixada em meu Github em https://github.com/deivisonarthur/phpquery , após feito do download vamos descompactar e colocar dentro da pasta do projeto e analizar o código abaixo.
Página test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Hello World!</title> </head> <body> <div>oioi</div> <div id="deivison">Deivison</div> <div class="arthur">Arthhur</div> </body> </html>
<?php
include_once 'phpQuery/phpQuery/phpQuery.php';
$file = 'test.html'; // página que será capturados os textos
phpQuery::newDocumentFileHTML($file); // instanciando a classe com a variavel da url
echo '<h2>O contedudo da tag html Title é</h2>';
$titleElement = pq('title'); // capturando o TITULO do documento test.html
echo '<p>' . htmlentities( $titleElement->html() ) . '</p>'; // exibindo o resultado
echo '<h2>O contedudo dos divs é</h2>';
$titleElement2 = pq('div'); // capturando todos os elementos DIVs do documento test.html
echo '<p>' . htmlentities( $titleElement2->html() ) . '</p>'; // exibindo o resultado
echo '<h2>O contedudo do ID deivison é</h2>';
$titleElement3 = pq('#deivison'); // capturando elemento de ID deivison do documento test.html
echo '<p>' . htmlentities( $titleElement3->html() ) . '</p>'; // exibindo o resultado
echo '<h2>O contedudo da Classe arthur é</h2>';
$titleElement4 = pq('.arthur'); // capturando todos os elementos da CLASS Arthur do documento test.html
echo '<p>' . htmlentities( $titleElement4->html() ) . '</p>'; // exibindo o resultado
?>
O link para documentação do phpQuery é http://code.google.com/p/phpquery/
Outros exemplos de uso do phpQuery
Exemplo um pouco mais avançado que captura o ID, imagem, link e preço do site Template Moster
require('phpQuery.php');
<pre>$type = 43;
$domain = 'http://www.templatemonster.com';
$url = $domain."/prestashop-themes.php?type={$type}&from=";
$pageNumber = 0;
$templateNumber = 0;
do
{
$pageNumber++;
phpQuery::newDocumentFileHTML($url.$pageNumber,null);
$validPage = pq('.thumbnail_wrapper')->html();
if($validPage)
{
$templates = pq('.preview_box td:not(.nav)');
foreach($templates as $t)
{
$templateNumber++;
if(trim(pq($t)->html()))
{
$imageSmall = pq($t)->find('.thumbnail_wrapper img')->attr('src');
$demoLink = $domain.pq($t)->find('.picture_menu a:nth-child(1)')->attr('href');
$productLink = $domain.pq($t)->find('.picture_menu a:nth-child(2)')->attr('href');
$price = pq($t)->find('.price-l span:eq(1)');
$price = trim(str_replace('$','',$price));
$imageBig = str_replace('m.jpg','prestashop-b.jpg',$imageSmall);
preg_match('/([\d]+)/', $productLink, $match);
$productId = $match[0];
echo $templateNumber.';'.$productId.';'.$productLink.';'.$price.'< br/ >';
$imageFile = "img/{$fileNumber}.jpg";
if(!file_exists($imageFile))
file_put_contents($imageFile, file_get_contents($imageBig));
}
}
}
}while($validPage);
Outro exemplo Utilizando o CURL para captura dos dados de endereço pelo CEP diretamente na base dos correios.
<?php
include('phpQuery-onefile.php');
function simple_curl($url,$post=array(),$get=array()){
$url = explode('?',$url,2);
if(count($url)===2){
$temp_get = array();
parse_str($url[1],$temp_get);
$get = array_merge($get,$temp_get);
}
$ch = curl_init($url[0]."?".http_build_query($get));
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($post));
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
return curl_exec ($ch);
}
$cep = $_GET['cep'];
$html = simple_curl('http://m.correios.com.br/movel/buscaCepConfirma.do',array(
'cepEntrada'=>$cep,
'tipoCep'=>'',
'cepTemp'=>'',
'metodo'=>'buscarCep'
));
phpQuery::newDocumentHTML($html, $charset = 'utf-8');
$dados =
array(
'logradouro'=> trim(pq('.caixacampobranco .resposta:contains("Logradouro: ") + .respostadestaque:eq(0)')->html()),
'bairro'=> trim(pq('.caixacampobranco .resposta:contains("Bairro: ") + .respostadestaque:eq(0)')->html()),
'cidade/uf'=> trim(pq('.caixacampobranco .resposta:contains("Localidade / UF: ") + .respostadestaque:eq(0)')->html()),
'cep'=> trim(pq('.caixacampobranco .resposta:contains("CEP: ") + .respostadestaque:eq(0)')->html())
);
$dados['cidade/uf'] = explode('/',$dados['cidade/uf']);
$dados['cidade'] = trim($dados['cidade/uf'][0]);
$dados['uf'] = trim($dados['cidade/uf'][1]);
unset($dados['cidade/uf']);
die(json_encode($dados));
Esse exemplo acima é ótimo! Melhor do que pagar pelo ceplivre ou usar um POG para um site que você não conheça a procedência, correto?
Ao invés do phpQuery, podiamos ter usado o YQL, porém teriamos dobrado o numero de requições, pois chamariamos o servidor do yahoo que por sua vez chamaria o servidor dos correios e nem sempre precisamos requisitar via CURL o site, eu somente utilizo o CURL quando vejo necessidade de uma resposta do site que estou requisitando, como é o cas do site dos correios que requisito via URL http://m.correios.com.br/movel/buscaCepConfirma.do onde se tem um formulário e é necessário enviar dados para capturar o retorno esperado.
Espero ter ajudado!


Claudia
Muito interessante !
meninaatreviida.blogspot.com
Testador
Como faço, no primeiro exemplo, para extrair as imagens do site?
Deivison Arthur L. Serpa
Opa amigo, segue informação, mas posso te adiantar que realmente é muito fácil trabalhar com o phpquery, recomendo executar os tutoriais, inclusive o segundo exemplo.
$titleElement = pq(‘img.iddaimagem’); // capturando a imagem com a classe chamada iddaimagem do site
echo htmlentities( $titleElement->html() ); // exibindo o resultado
Caso tenha mais de uma imagem o $titleElement irá virar um array e bastará dar um foreach($titleElement as $t) para exibir todas as imagens.
Gustavo Bauer Machado
Poderia me dar uma ajuda?
preciso pegar os dados desse site https://memphis.ulbranet.com.br/ALEPH
só que esta retornando vaziu o código esta abaixo
html());
?>