Como Extrair Metadados de Páginas Web
Portuguese (Português) translation by Erick Patrick (you can also view the original English article)



O Que Criaremos
Recentemente, começamos a criar uma comunidade na plataforma Yii de Programando com Yii2: Criando Comunidade com Comentários, Comartilhamento e Votação (Entato Tuts+). Queríamos facilitar o compartilhamento de links relacionados ao conteúdo, no site. Embora seja fácil para pessoas colarem links em formulários, é complicado prover título e fonte da informação.
No tutorial de hoje, mostraremos como usar PHP para extrair metadados comuns de páginas web e facilitar a participação dos usuários, além de criar serviços mais interessantes.
Lembrem-se, sempre participamos dos tópicos nos comentários abaixo, então digam o que acham! Ou entre em contato via Twitter, @lookahead_io.
Começando
Primeiro, construímos um formulário para adicionar links. Também criamos um botão Lookup que usa Ajax para requisitar a extração dos metadados da página.



Apertando Lookup chama Link::grab() via ajax:
1 |
$(document).on("click", '[id=lookup]', function(event) { |
2 |
$.ajax({ |
3 |
url: $('#url_prefix').val()+'/link/grab', |
4 |
data: {url: $('#url').val()}, |
5 |
success: function(data) { |
6 |
$('#title').val(data); |
7 |
return true; |
8 |
}
|
9 |
});
|
10 |
});
|
Extraindo a Página
Link::grab() invoca fetch_og() que imita um rastreador para capturar a página e obter os metadados via DOMXPath:
1 |
public static function fetch_og($url) |
2 |
{
|
3 |
$options = array('http' => array('user_agent' => 'facebookexternalhit/1.1')); |
4 |
$context = stream_context_create($options); |
5 |
$data = file_get_contents($url,false,$context); |
6 |
$dom = new \DomDocument; |
7 |
@$dom->loadHTML($data); |
8 |
$xpath = new \DOMXPath($dom); |
9 |
# query metatags with og prefix
|
10 |
$metas = $xpath->query('//*/meta[starts-with(@property, \'og:\')]'); |
11 |
$og = array(); |
12 |
foreach($metas as $meta){ |
13 |
# get property name without og: prefix
|
14 |
$property = str_replace('og:', '', $meta->getAttribute('property')); |
15 |
$content = $meta->getAttribute('content'); |
16 |
$og[$property] = $content; |
17 |
}
|
18 |
return $og; |
19 |
}
|
Em nosso caso, substituímos as tags og: acima, mas o código abaixo busca vários outros tipos de tags:
1 |
$tags = Link::fetch_og($url); |
2 |
if (isset($tags['title'])) { |
3 |
$title = $tags['title']; |
4 |
} else if (isset($tags['metaProperties']['og:title']['value'])) { |
5 |
$title=$tags['metaProperties']['og:title']['value']; |
6 |
} else { |
7 |
$title = 'n/a'; |
8 |
}
|
9 |
return $title; |
10 |
}
|
Também podemos pegar outras tags como palavras-chave, descrição, etc. jQuery, então, adiciona o resultado ao formulário para o usuário enviar:



Indo Além
Temos uma tabela sources que falaremos mais depois. Mas, basicamente, sempre que uma nova URL é adicionada, a analisamos e colocamos seu domínio numa tabela Source:
1 |
$model->source_id = Source::add($model->url); |
2 |
... |
3 |
public static function add($url='',$name='') {
|
4 |
$source_url = parse_url($url); |
5 |
$url = $source_url['host']; |
6 |
$url = trim($url,' \\'); |
7 |
$s = Source::find() |
8 |
->where(['url'=>$url]) |
9 |
->one(); |
10 |
if (is_null($s)) {
|
11 |
$s=new Source; |
12 |
$s->url = $url; |
13 |
$s->name = $name; |
14 |
$s->status = Source::STATUS_ACTIVE; |
15 |
$s->save(); |
16 |
} else {
|
17 |
if ($s->name=='') {
|
18 |
$s->name = $name; |
19 |
$s->update(); |
20 |
} |
21 |
} |
22 |
return $s->id; |
23 |
} |
Por hora, atualizamos os nomes das fontes para parecem mais limpos para o usuário, como ABC News, BoingBoing e Vice:



Em um próximo episódio, esperamos usar APIs disponíveis gratuitamente para obter o nome de um site. É estranho não ter uma metatag para isso. Ah se a Internet fosse perfeita...
Sites Pagos
Alguns sites, como o The New York Times, não nos deixam extrair os metadados por cobrarem a leitura. Mas eles tem uma API. Não é fácil aprender pela documentação confusa, mas os desenvolvedores ajudam rapidamente no GitHub. Também queremos escrever sobre a busca de metadados para oter títulos do New Yotk Times em episódios futuros.
Finalizando
Esperamos que esse guia de extração tenha sido útil e que possamos usar em algum projeto. Se quisermos vê-lo em ação, podemos testá-lo no site Active Together.
Deixe suas ideias e feedback nos comentários. Também é possível contatar via @lookahead_io no Twitter. E visite a página de instrutor onde há outras séries, Construindo Sua Startup com PHP e Programando Com Yii2.



