Passo 1 · Módulo 1 · Extrair·Módulo 1 · Extrair · Extrair um guia que o scrape não vê
Do guia da Rocketseat ao Warp · Visual Course
Extrair um guia que o scrape não vê
O guia da Rocketseat vive num Notion que devolve 6 bytes para um scraper comum. Você vai entender por quê, e sair com a extração completa e fiel — emojis e typo incluídos.
A página-fonte deste curso inteiro. Esta lição destila como tirar 100% do conteúdo dela sem inventar nada — o insumo de tudo que vem depois.
Leia a versão simples, ou abra a camada técnica em qualquer seção.
1
A grande ideia
Uma página do Notion parece um site normal, mas o texto não vem no HTML: vem depois, montado por JavaScript no navegador. Quem baixa o HTML cru recebe uma casca vazia.
Pense como… pedir a planta de um apartamento decorado e receber só a planta baixa: as paredes estão lá, os móveis não. A analogia quebra num ponto — no Notion nem as paredes vêm, vem só a placa com o nome do prédio.
A página é uma SPA: o HTML inicial carrega um bundle que faz POST /api/v3/loadPageChunk e só então injeta os blocos no DOM. Um fetcher HTTP simples nunca executa esse JavaScript, então o que ele devolve é o <title> e pouco mais. A saída literal do brightdata scrape -f markdown nesta página foram 6 bytes: a string Notion.
O mesmo URL, duas ferramentas: uma lê bytes, a outra roda o navegador. A diferença é 6 bytes contra 3.544.As quatro camadas de uma página do Notion. Um fetcher HTTP para na primeira; o texto nasce na quarta.
Antes de rolar: o scrape devolveu 6 bytes. Quantos links externos o guia tem escondidos nesse HTML que só o navegador monta?
9. iTerm2, JetBrainsMono, iTerm2colorschemes, Fish Shell, Starship, bat, zoxide, eza e fzf. Todos foram extraídos casando cada <a href> com o texto da âncora — não adivinhando pela lista de plugins.
2
Escolher a ferramenta certa
Não existe uma ferramenta melhor: existe a barata que às vezes basta, e a cara que sempre funciona. A regra é começar pela barata e escalar quando a saída vier vazia.
A árvore de decisão que economiza tempo e dinheiro em qualquer extração.As duas subcomandos do mesmo CLI. A escolha é sobre onde o conteúdo mora, não sobre qualidade.
A sessão nomeada rs mantém o navegador vivo entre os comandos — abrir, ler o texto, ler o HTML, fechar.
terminal · extração completa em 4 comandos
brightdata browser --session rs open "$URL" --timeout 90000
brightdata browser --session rs get text -o page-text.txt
brightdata browser --session rs get html -o page.html
brightdata browser --session rs close
Como chegar:brightdata browser --help lista todos os subcomandos: snapshot, screenshot, scroll, network, cookies.
O que cada saída preserva. A extração fiel usa as duas: prosa do texto, links e emojis do HTML.
O get text devolve prosa limpa mas descarta atributos: os href somem e os emojis (que o Notion renderiza como <img alt="💜"> sobre um spritesheet) viram nada. O get html guarda os dois. Foi casando os dois que a extração ficou fiel: a prosa saiu do texto, os 9 links e os 4 emojis saíram do HTML.
3
Em uma imagem
As mesmas três camadas nas duas tentativas. O que muda é a rede: sem executar o bundle, a chamada de dados nunca acontece.Bytes de saída por método, na mesma URL. A escala fala sozinha.O inventário completo da página, item por item. O último número é o que uma extração honesta declara em vez de esconder.A sessão inteira, em ordem. Os passos 5 e 6 foram a tentativa (falhada) de acordar o bloco de vídeo.A sessão real que provou o problema. Seis bytes: o título da aba, nada do guia.
4
Fidelidade: o que quase se perde
Extrair não é só pegar o texto: é pegar o texto exatamente como está. Três coisas escapam por padrão — e as três estavam neste guia.
1 · Os emojis somem
O get text devolveu "Feito com pela Rocketseat." — com dois espaços e nada no meio. O Notion desenha emoji como <img alt="💜"> com um spritesheet no background; o extrator de texto joga fora a imagem.
Correção: varrer o HTML por alt="…" e reinserir. Recuperados: 🎨 no título, 💜 no crédito, 🔥 no vídeo, 💜 no rodapé.
2 · O typo do original
A página diz "Bora descobri na prática" — sem o r. A primeira versão do arquivo extraído "consertou" para descobrir.
Isso é um bug de extração, não uma melhoria: uma extração fiel reproduz o original, inclusive o que parece errado. Revertido para o texto verbatim.
3 · O que não dá para extrair
O bloco de vídeo é um notion-video-block com arquivo hospedado no próprio Notion — não é YouTube. A URL assinada só carrega sob interação do player; após rolar a página inteira, o bloco seguiu em Carregando… e nenhuma URL de mídia apareceu no browser network.
A resposta honesta é registrar o buraco, com o motivo, no próprio artefato — nunca inventar uma transcrição.
1 / 3
Troca cada <img alt="…"> pelo emoji e mostra o contexto ao redor, para saber onde reinserir.
recuperando os emojis do HTML
python3 - <<'PY'
import re
h = open('raw-page.html', encoding='utf-8').read()
plain = re.sub(r'<img[^>]*alt="([^"]{1,12})"[^>]*>', r'{\1}', h)
plain = re.sub(r'<[^>]+>', '', plain)
for m in re.finditer(r'\{([^}]{1,12})\}', plain):
print(repr(m.group(1)), '::', plain[m.start()-70:m.end()+70])
PY
Como chegar: Rode dentro da pasta extract/ do projeto, onde ficam raw-page.html e raw-page-text.txt.
Os três arquivos da extração. Guardar os brutos é o que permite refazer o diff meses depois e provar que nada mudou.As duas terminam com um arquivo. Só uma delas você pode defender.
EXTRAÇÃO
Por que o scrape devolveu 6 bytes?
clique para virar
A página é client-rendered: o HTML inicial só carrega o bundle JS. Sem executar o bundle, o texto nunca é injetado no DOM.
FIDELIDADE
O original tem um typo. O que fazer?
clique para virar
Manter verbatim. Extração fiel reproduz o original — corrigir é introduzir uma diferença que ninguém pediu.
HONESTIDADE
E o que não dá para extrair?
clique para virar
Registrar o buraco com o motivo, dentro do próprio artefato. Nunca preencher com invenção.
5
Experimente
A prova de que a extração está completa não é "eu li e parece completo": é um diff programático entre o texto bruto da página e o markdown final.
Como a extração foi provada
1
Normalizar os dois lados: tirar decoração markdown (**, `, [texto](url) → texto), colapsar espaços, remover emojis dos dois lados e aplicar NFKC.
2
Listar as 55 linhas de conteúdo do raw-page-text.txt e ignorar as 3 de chrome do Notion (Ir al contenido, Comienza ahora, Cargando…).
3
Para cada linha, checar se ela aparece no markdown normalizado.
4
Contar as ausentes. O alvo é zero.
→
Agora você: rode o mesmo diff depois de editar o arquivo extraído — qualquer parágrafo que você reescrever aparece como ausente na hora.
O pipeline da prova. Sem a normalização, a decoração do markdown gera 22 falsos ausentes.O resultado real. Zero linhas ausentes é o critério do D1 no SCOPE.md.
Revisão da lição 1
O brightdata scrape devolveu quase nada numa página. Qual é o próximo passo?
a está certa: o browser roda um navegador real e executa o JS que monta o DOM. b falha porque o problema não é bloqueio geográfico — é renderização no cliente; trocar de país devolve os mesmos 6 bytes. c parece esperto, mas o bundle não carrega os dados: ele os busca depois, numa chamada que só acontece dentro do navegador.
A página tem um typo evidente. A extração deve:
b está certa: o artefato precisa ser fiel à fonte; anotar é opcional, alterar não. a introduz uma divergência silenciosa entre artefato e original. c é melhor que a por ser rastreável, mas ainda entrega um texto que a fonte não tem.
Quer ver a extração de outra página que resiste? Me peça — o mesmo par scrape → browser resolve quase tudo. Na próxima lição a gente traduz cada instrução do guia, escrita para iTerm2, na chave equivalente do Warp.