O documento apresenta um resumo sobre coleta de dados na web (web crawling e scraping) utilizando PHP. Aborda definições, principais pontos como robots.txt e headers, além de apresentar pseudocódigos para listagem de páginas e extração de detalhes, com armazenamento em banco de dados MySQL.
3. Definições
Crawling (rastreador) = spider, rastreador, rastreador focado, robô.
Scraping (raspagem) = RI (Recuperação da Informação), EI (Extração da Informação).
Interpretação = data mining (mineração de dados), SQL, IA (Inteligência Artificial).
Devido a longos tempos de processamento usamos PHP-CLI - linha de comando (tela escura).
Coleta de dados - pelo menos 2 etapas :.
● busca / listagem
● detalhe / perfil
3
5. Curiosidades - Google (1998)
urls = [‘siteA.com’] #seed / sementes
foreach(urls as url){
requisicaoGET(siteA.com)
extrai(“<a href=’http://siteB.com’>link B</a>”)
requisicaoGET(‘siteB.com’)
extrai(“<a href=’http://siteC.com’>link C</a>”)
requisicaoGET(‘siteC.com’)
… e assim vai ...
Basicamente temos um esquema de GRAFOS.
Bread First Search - Busca em Largura
Deep First Search - Busca em Profundidade
5
- O primeiro crawling foi feito em 1993
- Google não é pioneiro - 1994 https://en.wikipedia.org/wiki/World-Wide_Web_Worm
6. Coleta de dados - O problema
1. Recuperar a informação (HTML) que está em um servidor web.
2. Fazer isso para uma grande quantidade.
3. Fazer isso automaticamente (robô).
4. Reunir informação (Banco de Dados)
5. Responder as perguntas (T-SQL) de quem te contratou.
6
8. Qual a sua pergunta ?
Caso de uso bem simples para a palestra :.
Quero vender um carro! Qual preço devo anunciar ?
Vamos supor que não existisse a tabela FIPE.
Qual a média de preço de um golf ano 2010 na internet ?
8
9. Principais pontos
● robots.txt
● header User-Agent
● RapidFire
● Rotating IP
● Horários de pico
● Duplicação de páginas
● RIAs e sites com autenticação
● Captchas
● Timeout
● BD Mysql
9
10. arquivo robots.txt
10
Usa o formato do Protocolo de
Exclusão de Robôs padrão,
serve para dar ordens
específicas para os robôs de
busca.
12. SSL && header User-Agent
Podemos recuperar a pagina HTML do servidor com varias funcoes PHP
● file
● fopen
● file_get_contents
Conforme o servidor alvo começa a ficar exigente temos que trabalhar com outras funções
● cURL
● stream_context_create
12
14. RapidFire
Evitar bombardear requisições no site alvo. Podemos usar um intervalo randômico.
sleep(mt_rand(5,10));
Esse código antes de qualquer requisição GET ou POST simula aleatoriedade.
14
15. IP
Podemos ser bloqueados pelo IP, neste caso podemos usar um proxy via Curl
$proxy = "1.1.1.1:33333";
$useragent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";
$url = "https://api.ipify.org/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION,'CURL_HTTP_VERSION_1_1' );
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYUSERPWD,'USER:PASS');
curl_setopt($ch, CURLOPT_USERAGENT,$useragent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
$result=curl_exec ($ch);
curl_close ($ch);
echo $result;
15
16. Auth && RIA - Rich Internet App (ajax)
Quando as informações são processadas no browser via AJAX - Problema para PHP
16
18. Captchas - usei cURL + Selenium
Extrair esta imagem Como ? GD?
1) cURL nao faz printScreen. Selenium sim.
2) Recortei o captcha - Salvei a img via GD.
3) Transformei todos os pixels não pretos em branco.
4) Com cURL envio esta imagem via POST para um programa
específico que acerta +-30%.
18
20. Timeout - CLI (Command Line Interface)
$_ = $_SERVER['_']; (Retorna o binário /usr/bin/php)
$restartMyself = function () {
global $_, $argv;
pcntl_exec($_, $argv);
};
register_shutdown_function($restartMyself);
set_error_handler($restartMyself , E_ALL);
Este codigo faz o script PHP rodar o
tempo todo, mesmo que finalize o loop
do BD ou se der erros.
20
22. BD (fazer a limpeza antes)
Eliminar espaços (“ “), quebras linha (n) e tabs (t) antes de armazenar no BD
preg_replace('/(?:ss+|n|t)/', ' ', $html);
Usar constraints UNIQUE para evitar repetidos.
UNIQUE KEY `uq_link_paginacao` (`link`,`paginacao`)
Tipos de dados no MYSQL exemplos de campos :
- flag/booleano : tinyint(1) default ‘0’
- paginas html : longtext()
Fique atento com o tamanho do BD : (Linux 2.4+ ext3 file system) +- 4TB
22
se não couber no seu computador - você está lidando com um BIGDATA
32. DOMDocument
32
Navega na árvore DOM até
chegar no nó desejado.
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach($dom->getElementsByTagName(‘a’) as $link){
echo $link->getAttribute(‘href’);
}
38. detalhes
PSEUDOCODIGO
$ids = $cn->query(“select id from detalhes where parsed=0”);
foreach($ids as $id){
$html = crawling($url . $id)
$arrayInfo = getInfoViaRegex($html)
$arrayInfo = getInfoViaDOM($html)
saveData2BD($arrayInfo)
}
function getInfoViaRegex($html){
$preco = preg_match(‘/<td><a>(.+)</a></td>/’,$html);
$ano = preg_match(‘/<td><a>(.+)</a></td>/’,$html);
return [‘preco’=>$preco,’ano’=>$ano];
}
function getInfoViaDOM($html){
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach($dom->getElementsByTagName(‘a’) as $link){
if($link->getAttribute(‘class’)==’preco’){
$preco = $link->item(0)->nodeValue;
}
}
...
return [‘preco’=>$preco,’ano’=>$ano];
}
function saveData2BD($arrayInfo){
global $cn; extract($arrayInfo);
$q=”update detalhes set parsed=1,campo2=$campo2”;
return $cn->exec($q);
} 38
39. BD - análise dos dados
listagem
id
url UNIQUE
pagina
total
detalhes
id
golf_id UNIQUE
parsed
listagem_id FK
preco
id url pg total
1 icarros.com/c=golf&...&pag=1 1 160
2 icarros.com/c=golf&...&pag=2 2 160
3 webmot.com/c=golf&...&pag=1 1 860
id golf_id FK preco
1 GFYR544 1 30000
2 KPYR774 1 29500
3 FFFF765445FFVYRE65HGF 3 33000
39
40. BD - análise e auditoria dos dados
40
select distinct sum(total) from listagem group by total;
select avg(preco) as media from detalhes;