APIs públicas são uma das coisas mais bacanas da internet, a força propulsora da revolução web 2.0. A possibilidade da criação de mashups através de dados disponibilizados publicamente por sites como Flickr, NYTimes, Digg e outros, nos permite uma possibilidade de combinações limitadas apenas à nossa imaginação. Porém, como nem tudo são flores, nem sempre os sites que disponibilizam seus dados fornecem 100% das funcionalidades oferecidas no próprio site em si. Na verdade, nem deveriam.
Como faríamos para extender as possibilidades fornecidas por estas Apis?
Scraping
De acordo com o Wikipedia:
“Web scraping (or Web harvesting, Web data extraction) is a computer technique of extracting information from websites using specially coded software programs. Usually, such software programs simulate human exploration of the Web by either implementing the low-level Hypertext Transfer Protocol (HTTP), or embedding certain full-fledged Web browsers, such as the Internet Explorer (IE) and the Mozilla Web browser.”
Resumindo de maneira mais técnica, (X)HTML é no fundo XML. Ao navegarmos pelo conteúdo de uma página, podemos extrair informações através de parsing desse conteúdo. Existem diversas ferramentas, tanto de parsing quanto de scraping:
Scraping
- ScRUBYt
- Mechanize
Parsing
- Hpricot
- Nokogiri
- REXML
Neste exemplo, utilizarei o Hpricot, por razões pessoais. Nunca parei para avaliar critérios como velocidade, facilidade, etc…
Extendendo API do Delicious
O site Delicious é uma das mais úteis ferramentas disponíveis na web. É um site que, ao meu ver, é bem definido em duas partes: personal bookmarking e social bookmarking. Na primeira, você o utiliza como um gerenciador centralizado de bookmarks, salvando tudo o que ver pela frente e organizando através de tags e bundles. Na segunda opção, você utiliza os recursos como busca em bookmarks de outros usuários, ranking de links mais votados( a la digg), entre outros.
Ambas as opções são ótimas e se complementam, porém, a API do Delicious nos fornece apenas métodos de acesso à parte “personal” dos bookmarks. E quanto à parte “social”?
Trazendo o “Social” Para o Bookmarking
Ao consultarmos a documentação da API do Delicious, percebemos que os métodos disponíveis na API são de escopo do usuário, permitindo gerenciar os bookmarks pessoais através de mensagens HTTP:
- Update
- posts/update – Check to see when a user last posted an item.
- Posts
- posts/add – add a new bookmark
- posts/delete – delete an existing bookmark
- posts/get – get bookmark for a single date, or fetch specific items
- posts/dates – list dates on which bookmarks were posted
- posts/recent – fetch recent bookmarks
- posts/all – fetch all bookmarks by date or index range
- posts/all?hashes – fetch a change detection manifest of all items
- posts/suggest – fetch popular, recommended and network tags for a specific url
- Tags
- tags/get – fetch all tags
- tags/delete – delete a tag from all posts
- tags/rename – rename a tag on all posts
- Tag Bundles
- tags/bundles/all – fetch tag bundles
- tags/bundles/set – assign a set of tags to a bundle
- tags/bundles/delete – delete a tag bundle
Mas tão útil quando gerenciar o seu bookmark é dar uma espiada no que anda rolando de interessante, através de listas como a de links populares. Então, vamos colocar a mão na massa para criarmos novos métodos de acesso ao delicious.
Os métodos que serão criados nessa primeira versão são:
- Popular
- Hot List
- Recent
- Search
Utilizando o indispensável Firebug, conseguiremos descobrir a hierarquia dos objetos da página. No exemplo abaixo, consigo achar os elementos que representam o título e o link de cada url listada.

Tanto o link, quanto o título mostrados na imagem acima podem ser capturado, com o uso do HPricot, através de parsing dos elementos contidos dentro da div da classe “data”:
#Assumindo que 'result' é o trecho da página que representa cada bookmark mostrado na página text = (result/"div[@class='data']/h4/a[@href").first.inner_text url = (result/"div[@class='data']/h4/a[@href").first['href']
Dessa maneira, ao iterar sobre cada item da lista, ao final já teremos no mínimo uma lista de links interessantes para mostra. Outras buscas devem ser feitas para cada elemento que queiramos adicionar aos resultados finais, como autor do link, número de pessoas que salvaram e tags.
O autor por sua vez, pode ser consultado da seguinte maneira:
name = (result/"div[@class='meta']/span/a[@class='user").first['href'].gsub("/", "")
E seguindo nesse procedimento, vamos recheando a nossa pseudo-api. O processo é braçal mesmo, dividido nas seguintes partes:
1. Acessar a URL a ser analisada, através do Firefox
2. Descobrir os elementos DOM de cada elemento que queremos salvar
3. Traduzir a consulta para alguma forma que o Hpricot reconheça (nos exemplos, utilizo XPath)
4. Juntar tudo com métodos publicos de acesso com Ruby.
Resultados
Após o desenvolvimento da API, podemos testar os outputs apresentados para ver como ficou o funcionamento final. Caso queiram brincar, o código está disponível no Github.
Confiram como fica uma consulta a 5 dos links mais populares do momento no delicious:
d = Delicious::Collector.new
links = d.popular
links[1..5].each do |link|
puts '------------------------------------------'
puts "Text: #{link.text}"
puts "URL: #{link.url}"
puts "People: #{link.people}"
puts "Posted By: #{link.posted_by.name}"
puts "Tags: #{link.tags * ','}"
end
######## Resultado ############
——————————————
Text: 99 ways to make your computer blazingly fast
URL: http://helpdeskgeek.com/windows-xp-tips/99-ways-to-make-your-computer-blazingly-fast/comment-page-1/
People: 476
Posted By: jimbeau
Tags: windows,computer,tips,performance,speed
——————————————
Text: 5 Ways to Instantly Write Better CSS – NETTUTS
URL: http://nettuts.com/tutorials/html-css-techniques/5-tips-to-writing-better-css/
People: 280
Posted By: ani625
Tags: css,tips,webdesign,design,webdev
——————————————
Text: Facebook’s New Terms Of Service: “We Can Do Anything We Want With Your Content. Forever.”
URL: http://consumerist.com/5150175/facebooks-new-terms-of-service-we-can-do-anything-we-want-with-your-content-forever
People: 352
Posted By: mlanger
Tags: facebook,privacy,copyright,legal,socialnetworking
——————————————
Text: 40+ Useful & Handy Web Designer’s Web Services & Tools | Noupe
URL: http://www.noupe.com/tools/40-useful-handy-web-designers-web-services-tools.html
People: 566
Posted By: anadeixis
Tags: webdesign,tools,resources,design,reference
——————————————
Text: 50 Tutorials To Get You Started With Gimp | LinuxHaxor.net
URL: http://www.linuxhaxor.net/2009/02/09/50-tutorials-to-get-you-started-with-gimp/
People: 251
Posted By: pavs
Tags: gimp,tutorial,tutorials,graphics,linux
Bacana, não?
Pontos Negativos da Abordagem
Na verdade, eu utilizar scraping em um site, estamos de certa forma o hackeando – no “bom” sentido do termo -, aonde informações são adquiridas na base da força bruta. Em sites aonde existem APIs públicas, se parte das informações não estão disponveis, provavelmente isso se deve a uma decisão arquitetural ou de direito de propriedade. Por esses e outros motivos, não é recomendado o uso desta abordagemna criação de ferramentas comerciais.
Além disso, como scraping se fundamenta diretamente na navegação de uma estrutura definida, o funcionamento de sua aplicação depende diretamente da manutenção desta estrutura por parte do site que você efetua o scraping. Um exemplo real ocorreu quando, no ano passado, o site do delicious passou por reformulações fazendo com que esta extenção que eu criei parasse de funcionar em cerca de 70% das funções.
Considerações Finais
Com um pouquinho mais de esforço é possível, por exemplo, criar um sistema de widget semelhantes aos do Digg , para ser adicionado à um blog pessoal. O resto fica a cabo da imaginação do desenvolvedor. A internet é uma grande fonte de informações espalhadas e cabe a nós utilizarmos a imaginação para a criação de novas maneiras de coletar e apresentar dados. Scraping é bacana, mas vicia. Use com moderação.
Código fonte: http://github.com/tbueno/delicious-ext/tree/master


Comentário(s) deste Post
1 Comentário deixado
Feb 19, 2009 - 8:40 pm
[...] Como já foi dito antes, eu amo APIs e a possibilidade infinita que elas proporcionam. Nada melhor do que uma coleção de informações pessoais deixadas em sites que eu utilizo para rechear minha página de apresentação. A maioria das APIs disponíveis publicamente já possuem sua implementação em Ruby, tornando o uso das mesmas extremamente simples através das rubygems. [...]