Catálogo 6 min
Spinewatch
Contents · 8 sections
1. O que é isso?
O Spinewatch observa quanto custam os livros.
Você dá a ele uma lista de livros com os quais você se importa e diz onde cada um é vendido: uma página da Amazon, uma página do Mercado Livre. Toda noite, enquanto você dorme, ele vai lá olhar essas páginas e anotar o preço. Uma linha por livro, por loja, por dia.
A parte que importa é que ele nunca joga uma página fora. Depois de alguns meses você não tem “o preço de hoje”, você tem uma linha que vai até março, e você pode olhar para ela e ver que o livro que você está prestes a comprar por R$ 89 já esteve R$ 62 duas vezes este ano e provavelmente vai estar R$ 62 de novo.
2. Por que eu construí isso?
Porque eu vivia fazendo uma pergunta que nada respondia: este preço é bom, ou só parece bom?
Livrarias online mudam preço o tempo todo. Não sazonalmente, não na Black Friday, o tempo todo. O mesmo livro pode ter três preços diferentes na mesma semana por um motivo que você nunca vai saber. E a loja fica feliz em te mostrar um número riscado ao lado do atual, o que não diz nada, porque a loja escolheu os dois números.
3. Como funciona
São três peças compartilhando um arquivo: algo que sai por aí olhando preços, algo que os guarda, e uma página web para olhar o que foi guardado. Vamos na ordem em que os dados se movem.
3.1. O catálogo
Você adiciona um livro. Título, autor, ISBN. O Spinewatch confere a conta do ISBN, aquele número de código de barras na contracapa, porque ISBNs têm um dígito verificador embutido e um digitado errado dá para pegar antes de salvar.
Aí você liga esse livro às páginas reais onde ele é vendido. Um livro pode apontar para várias lojas, e uma loja pode ser desligada sem perder nada que ela já tenha registrado.
Aqui vai uma decisão que parece chata e não é: o Spinewatch liga a uma página específica, uma vez, e recheca essa mesma página para sempre. Ele não busca o livro toda noite.
É tentador fazer isso, daria menos trabalho de configuração, mas quebra a coisa toda silenciosamente. Resultados de busca variam. Hoje à noite o primeiro resultado é o brochura, amanhã é um usado de um vendedor terceiro, semana que vem é o box de três volumes. O número ficaria mudando e você acharia que estava vendo um preço se mover quando na verdade estava vendo os resultados de busca se moverem. Fixar a página te custa trinta segundos uma vez e te compra uma linha que significa uma coisa só.
3.2. A caminhada noturna
Às 3 da manhã, a máquina acorda e ela desce a lista.
É deliberadamente sem pressa. Visita uma página por vez, nunca várias ao mesmo tempo, e espera entre dois e cinco segundos aleatórios entre requisições para a mesma loja. Aleatórios, não exatos: uma requisição a cada exatos três segundos é um robô se anunciando.
Nada disso precisa ser rápido. Ninguém está esperando; os resultados são lidos na manhã seguinte. Então ele se comporta como um visitante educado, porque não há razão para não ser, e porque um rastreador que martela uma loja é um rastreador que é bloqueado e para de funcionar.
3.3. Quando uma loja diz não
Às vezes uma loja não entrega a página. Você recebe um CAPTCHA, ou um muro de “detectamos atividade incomum”.
Para esses casos o Spinewatch mantém uma segunda opção, mais pesada: ele abre um navegador de verdade (um Chrome real, invisível, sem janela), carrega a página como uma pessoa faria, e lê o preço dali. Funciona muito mais vezes. Também leva vinte segundos e algumas centenas de megabytes de memória.
Então o navegador é o último recurso, com duas travas.
A primeira é que ele só entra em cena para um tipo de falha. Se a loja nos bloqueou, ok, tente o navegador. Se a página carregou bem e a gente simplesmente não achou o preço nela, o navegador é inútil: ele gastaria vinte segundos buscando exatamente a mesma página e falhando exatamente do mesmo jeito. Isso não é uma porta trancada, isso é a gente não saber onde olhar.
A segunda é um orçamento: 25 usos por noite, aí ele para. Sem esse teto, uma loja decidindo bloquear tudo comeria a noite inteira e o resto dos livros ficaria sem checagem. Com ele, a loja ruim custa uma quantia conhecida, todo o resto ainda é feito, e o que restou fica marcado como bloqueado e são tentadas de novo amanhã.
3.4. Falha é dado
Toda checagem escreve uma linha, e toda linha diz o que aconteceu:
| O que ela diz | O que significa |
|---|---|
| ok | Pegou o preço. Esta é a única que carrega um número. |
| unavailable | A página carregou bem, o livro só não está à venda agora. Isso é um fato real, não uma falha. |
| blocked | A loja se recusou a nos mostrar a página. |
| not found | A página sumiu. O link provavelmente está velho. |
| parse error | A gente pegou a página, só não conseguiu achar o preço nela. |
| error | Alguma outra coisa quebrou. A mensagem é guardada. |
Blocked e Parse Error parecem parecidas e significam coisas opostas. Blocked significa que a loja está reagindo e eu deveria ser mais gentil. Parse error significa que a loja redesenhou a página e meu código está lendo a parte errada dela. Vá consertar. Se você juntar os dois como “falhou”, você jogou fora a única pista que te diz qual dos dois problemas você tem.
E o próprio banco de dados garante a regra. Ele é montado de forma que um preço só pode existir numa linha marcada como ok. Literalmente não há como escrever uma checagem falha com um número junto, nem uma bem-sucedida sem número. Não é uma convenção que eu tenho que lembrar, é uma parede. Um parse error não pode virar um R$ 0,00 num gráfico, porque o arquivo não aceita.
3.5. Olhando para isso
O lado web são três páginas, atrás de uma senha.
O catálogo: tudo que você rastreia, cada livro com suas lojas e o último preço que cada uma devolveu.

Um livro específico: o gráfico e a tabela completa embaixo dele. Toda noite desde que você o adicionou, preço ou motivo. Esta é a página que o sistema inteiro existe para produzir.

Lojas: ligue ou desligue uma. Uma loja desativada é pulada hoje à noite e mantém todo preço que já registrou.
