YQL + Y! Geocoding API + Google Maps

14/7/2009 | Tags:, , , , , | Escrito por: Dirceu Pauka Jr.

Sábado eu comecei a procurar uma casa para morar. Eu preciso de uma casa grande e sem vizinhos, assim posso fazer umas festinhas e vender minha cervejinha artesanal. A casa também precisa ficar próxima ao “busão da UEL“.

O problema: nenhum site de imobiliária presta, quanto mais em Londrina.

Poucos sites de imobiliárias mostram as opções em um mapa e nenhuma das páginas que “unem os imóveis de várias imobiliárias” funcionam.

A solução: escrever código.

Com Yahoo Query Language (YQL) eu busquei as “casas para alugar” de 7 imobiliárias.
De fato essa é a parte mais complicada e demorada uma vez que cada imobiliária usa um “padrão” diferente para apresentar as informações e o trabalho aumenta ainda mais por causa da má construção de certas páginas.

Das 7 imobiliárias foi possivel extrair cerca de 100 casas para locação.

Para inserir as informações no mapa foi preciso de uma API de Geocoding. Esse tipo de serviço transforma um endereço (rua e número) em coordenadas geográficas (latitude, longitude).
Minha primeira tentativa foi usar a API de Geocoding do Google porém a Geocoding API do Yahoo! se saiu melhor quando o endereço tem “sujeira” (erros de digitação e/ou encoding zuado).

O resultado:

Picture-6

Muito mais fácil agora.

Tech stuff

O código que une os resultados das imobiliárias foi escrito em Ruby.
A gem typhoeus faz as requisições HTTP.
YQL foi usado para filtrar o conteúdo das páginas.
A gem geokit permite fazer Geocoding em apenas uma função: YahooGeocoder.geocode(”rua”).
Memcache faz cache dos resultados (muitas requisições HTTP machucam).
Sinatra para que o código Ruby vire uma aplicação web.
Google Maps API para inserir os resultados no mapa.

Códigos:
nerd_searching_house.rb
/ index.erb

Exemplo

Veja o resultado da brincadeira.

Colocar em produção e manter esse “toy project” não está nos meus planos. O exemplo ficará desatualizado em breve e se você precisar de algo atualizado fique a vontade para fazer o código funcionar ;)



Widget do Submarino com YQL

4/6/2009 | Tags:, , , , , , | Escrito por: Dirceu Pauka Jr.

Meu último post foi uma tentativa de explicar o funcionamento da Yahoo Query Language. No final falei da possibilidade de se fazer um Widget do Submarino com a YQL e agora volto para implementar o prometido.

YQL

Como eu disse existe um post explicando a YQL, porém aqui vai uma explicação rápida:

A YQL pode ser usada para buscar dados nas APIs do Yahoo (Flickr, Delicious, Placemaker, Maps, …), nas APIs do DataTables (Twitter, Amazon, GeoLocation, …) ou em qualquer outro documento da web (página HTML).

Para mostrar como a busca em um documento qualquer da web é feita, escrevi o seguinte código:

Para testar use o console da YQL ou veja teste dessa busca. O YQL vai retornar o conteúdo pedido em XML ou JSON.

JSONP

“JSON with Padding” é uma técnica que permite o carregamento assíncrono de informações de um domínio externo.

Toda biblioteca de JavaScript que se preze possui um método para esse procedimento.
jQuery: $.getJSON(url, function(data) { // callback });
MooTools: Request.JSON([options]);

A implementação desse tipo de requisição é bem simples.

Sabemos que o retorno de um arquivo chamado pela tag script é imediatamente executado pelo interpretador JavaScript.

Também sabemos que um objeto em JS pode ser representado por {} e pode conter pares de chave/valor. Ex: var Objeto = { chave: ‘valor’ };

Assim sendo, o que precisamos agora é que o conteúdo de um arquivo que vai ser requisitado utilizando a tag script seja uma chamada a nossa função previamente declarada.

Atente que ao contrario do xhttprequest o elemento HTML script não possui limitações quanto ao domínio que a requisição pode ser feita. Porém, para que a técnica funcione é necessário que o servidor requisitado retorne (em texto puro) uma chamada para nossa função.

Requisição:
http://pomoti.com/arquivo.php?callback=recebe_json
PHP simples para retorno:
echo $_GET['callback'] . ‘( {chave: “valor”} )’;
Retorno:
recebe_json( {chave: ‘valor’} );

Todos webservices que queiram trabalhar com JSON devem, então, aceitar um parâmetro para envio de callback.

Widget do Submarino

Fundamentadas as técnicas necessárias para a implementação vamos ao código.

// tentando duas querys diferentes. a estrutura do submarino pode ser alterada e isso evita quebrar
getJSON(query1);
}
function getJSON(query) {
// monta a requisição REST
var url = ‘http://query.yahooapis.com/v1/public/yql?q=’+
encodeURIComponent(query)+
‘&format=json’+
‘&callback=Submarino.recebe’;

// se tag head não existir, cria uma para evitar problemas
if (!document.getElementsByTagName(’head’)[0]) {
document.getElementsByTagName(’body’)[0].appendChild( document.createElement(’head’) );
}

// adiciona o elemento