Como Hackear Reservas de Roof Terraces em Londres com Python

A Tragédia dos Comuns Digital: O Desafio de Escalar Reservas em Espaços Públicos

Londres possui alguns dos mirantes mais espetaculares do mundo, e o melhor de tudo: muitos deles são totalmente gratuitos devido a acordos de planejamento urbano (conhecidos como acordos da Seção 106). No entanto, tentar reservar um horário no Horizon 22, Sky Garden ou The Lookout tornou-se uma tarefa quase impossível para humanos comuns. Os ingressos esgotam em segundos, não porque existem milhões de turistas clicando simultaneamente, mas devido à presença massiva de bots de agendamento e sistemas proprietários ineficientes que criam uma escassez artificial.

As informações originais sobre a infraestrutura física e a experiência de visitação desses espaços foram detalhadas no Artigo de Origem, que serve como base empírica para o nosso estudo de caso de engenharia reversa. Como desenvolvedores, quando nos deparamos com um sistema de reserva que falha sob carga ou que favorece scalpers, nossa resposta imediata é: podemos automatizar isso de forma mais eficiente e justa?

Neste guia técnico profundo, vamos analisar a arquitetura dos sistemas de reserva por trás dos principais terraços gratuitos de Londres, realizar a engenharia reversa de suas APIs ocultas, construir um bot de monitoramento resiliente em Python e discutir como transformar essa automação em um modelo de Micro-SaaS lucrativo.

Engenharia Reversa dos Portais de Reserva (Sky Garden, Horizon 22 e Lookout)


Asset por BlackDog1966 via Pixabay

Para automatizar qualquer sistema de reservas, primeiro precisamos entender como ele se comunica com o servidor. A maioria dessas plataformas não reconstrói a página inteira a cada clique; elas utilizam APIs REST assíncronas que retornam payloads em JSON contendo a disponibilidade de slots de tempo.

Análise de Tráfego e Descoberta de APIs Ocultas

Ao abrir o console de desenvolvedor do Google Chrome (F12) na aba Network (Rede) e filtrar por requisições do tipo Fetch/XHR enquanto navega pelo calendário do Horizon 22, podemos identificar o endpoint exato que retorna os dias disponíveis. Em vez de renderizar o calendário visualmente, o frontend faz uma requisição GET para um endpoint estruturado da seguinte forma:

GET /api/v1/slots?venue_id=102&start_date=2026-06-01&end_date=2026-06-30 HTTP/1.1
Host: booking.horizon22.co.uk
Authorization: Bearer [JWT_TOKEN]
Accept: application/json

O payload de resposta é um JSON limpo, que nos diz exatamente quais dias possuem vagas e quantos ingressos restam por horário:

{
  "success": true,
  "data": [
    {
      "date": "2026-06-15",
      "available_slots": [
        {"time": "09:15", "capacity_remaining": 4, "ticket_type_id": 901},
        {"time": "10:30", "capacity_remaining": 1, "ticket_type_id": 901}
      ]
    }
  ]
}

Contornando Proteções: Cloudflare, Captchas e TLS Fingerprinting

Plataformas de alta demanda frequentemente implementam firewalls de aplicação web (WAF) como Cloudflare ou Akamai para mitigar ataques de negação de serviço (DDoS) e bloquear scrapers. Se você tentar fazer uma requisição simples usando a biblioteca requests do Python, receberá imediatamente um erro 403 Forbidden devido ao bloqueio de User-Agent ou, pior, um desafio de JavaScript (Cloudflare Turnstile).

Para contornar essas proteções de forma ética e robusta, precisamos emular perfeitamente o comportamento de um navegador real. Isso envolve:

  • TLS Fingerprinting (JA3): Os WAFs modernos analisam o aperto de mão (handshake) TLS do seu cliente HTTP. Bibliotecas padrão como urllib ou requests possuem assinaturas TLS muito diferentes do Chrome ou Firefox. Usaremos a biblioteca curl_cffi ou tls_client em Python para forçar o handshake a se parecer exatamente com o de um navegador moderno.
  • Automação Headless com Evasão: Em vez de requisições HTTP puras, utilizaremos o Playwright em modo headless combinado com o pacote playwright-stealth para ocultar variáveis de ambiente que revelam a automação (como navigator.webdriver).

Arquitetura do Sistema: O Bot de Agendamento Open-Source (TerraceBot)

Para criar um sistema resiliente, não podemos confiar em um script síncrono simples que roda em loop infinito. Se o servidor cair ou a conexão oscilar, o bot falhará. Projetamos o TerraceBot utilizando uma arquitetura orientada a eventos, dividida em três microsserviços principais:

  1. Scraper/Monitor: Um worker leve que consulta continuamente os endpoints de disponibilidade usando proxies rotativos.
  2. Fila de Mensageria (Redis): Armazena os slots encontrados e gerencia o estado das tarefas de agendamento para evitar reservas duplicadas.
  3. Booking Engine (Playwright Worker): Quando um slot disponível é detectado, este worker é disparado para preencher o formulário de reserva, resolver captchas (usando serviços de API como 2Captcha ou CapSolver) e confirmar o agendamento.

Diagrama de Fluxo de Dados

[API de Disponibilidade] 
       │ (Polling via curl_cffi com Proxy Rotativo)
       ▼
[Monitor Worker] ──(Se houver vaga)──> [Fila Redis] ──> [Booking Worker (Playwright)]
                                                               │
                                                               ├──> [Confirmação de Reserva]
                                                               └──> [Notificação Telegram/Discord]

O Módulo de Scraping e Monitoramento em Tempo Real (Python)

Abaixo está a implementação do módulo de monitoramento utilizando curl_cffi para contornar o TLS Fingerprinting. Este script monitora a API de disponibilidade e envia um alerta assim que um slot livre é detectado.

import time
import json
from curl_cffi import requests

API_URL = "https://api.horizon22.co.uk/v1/slots?venue_id=102&start_date=2026-06-01&end_date=2026-06-30"
HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "application/json",
    "Accept-Language": "en-US,en;q=0.9",
    "Referer": "https://booking.horizon22.co.uk/",
    "Origin": "https://booking.horizon22.co.uk"
}

def check_availability():
    try:
        # Usando impersonate='chrome120' para emular o fingerprint TLS do Chrome
        response = requests.get(API_URL, headers=HEADERS, impersonate="chrome120", timeout=10)
        if response.status_code == 200:
            payload = response.json()
            for day in payload.get("data", []):
                date = day.get("date")
                slots = day.get("available_slots", [])
                if slots:
                    print(f"[ALERTA] Vagas encontradas para o dia {date}!")
                    for slot in slots:
                        print(f"  - Horário: {slot['time']} ({slot['capacity_remaining']} vagas restantes)")
                    trigger_booking_pipeline(date, slots)
        elif response.status_code == 403:
            print("[ERRO] Bloqueado pelo Cloudflare. Rotacionando proxy...")
        else:
            print(f"[ERRO] Status Code inesperado: {response.status_code}")
    except Exception as e:
        print(f"[ERRO] Falha na requisição: {str(e)}")

def trigger_booking_pipeline(date, slots):
    # Aqui conectamos com a fila Redis para disparar o worker do Playwright
    pass

if __name__ == "__main__":
    while True:
        print("[INFO] Verificando disponibilidade...")
        check_availability()
        time.sleep(30) # Intervalo de segurança para evitar rate limiting

O Módulo de Reserva Automatizada com Playwright

Uma vez detectada a vaga, o worker do Playwright entra em ação para simular a interação humana e finalizar o processo de checkout. O script abaixo demonstra como inicializar o navegador de forma furtiva e preencher os dados do usuário.

import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import use_stealth_async

async def perform_booking(target_date, target_time, user_info):
    async with async_playwright() as p:
        # Lançando o navegador com argumentos para evitar detecção
        browser = await p.chromium.launch(headless=True, args=[
            "--disable-blink-features=AutomationControlled",
            "--no-sandbox"
        ])
        context = await browser.new_context(
            viewport={"width": 1920, "height": 1080},
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        )
        page = await context.new_page()
        await use_stealth_async(page)

        # Navegando diretamente para a página de checkout do slot específico
        booking_url = f"https://booking.horizon22.co.uk/checkout?date={target_date}&time={target_time}"
        print(f"[WORKER] Acessando {booking_url}")
        await page.goto(booking_url, wait_until="networkidle")

        # Preenchendo o formulário de reserva
        await page.fill("input[name='first_name']", user_info['first_name'])
        await page.fill("input[name='last_name']", user_info['last_name'])
        await page.fill("input[name='email']", user_info['email'])
        await page.fill("input[name='phone']", user_info['phone'])
        
        # Aceitando os termos de serviço
        await page.click("input[type='checkbox']#terms-agreement")

        # Submetendo o formulário
        print("[WORKER] Submetendo reserva...")
        await page.click("button[type='submit']#confirm-booking")
        
        # Aguardando a tela de sucesso
        await page.wait_for_selector(".booking-success-confirmation", timeout=15000)
        print("[SUCESSO] Reserva concluída com êxito!")
        await page.screenshot(path=f"confirmation_{target_date}.png")
        
        await browser.close()

# Exemplo de execução do loop de eventos
# asyncio.run(perform_booking('2026-06-15', '10:30', {
#     'first_name': 'John', 'last_name': 'Doe', 
#     'email': 'john.doe@example.com', 'phone': '+447700900077'
# }))

Transformando Automação em Micro-SaaS: Monetização e Oportunidades de Mercado


Asset por ps_composition via Pixabay

Para desenvolvedores interessados em transformar scripts utilitários em fontes recorrentes de receita, a transição de um simples bot local para uma arquitetura multi-tenant é o caminho ideal. Explore mais sobre este ecossistema em nossa categoria de Automações e Micro-SaaS.

O mercado de turismo e conveniência em grandes metrópoles como Londres, Paris e Nova York é altamente lucrativo. Turistas de alto padrão e agências de viagens corporativas estão dispostos a pagar taxas de conveniência para garantir acesso a atrações exclusivas sem o estresse de monitorar calendários manualmente.

Modelos de Monetização para Bots de Conveniência

  • Notificação Premium (Freemium): O usuário se cadastra gratuitamente para receber alertas de vagas remanescentes no Telegram com 15 minutos de atraso. Assinantes premium (ex: £4.99/mês) recebem alertas instantâneos via SMS/WhatsApp com link direto de checkout pré-preenchido.
  • Concierge de Agendamento (SaaS Completo): O cliente insere seus dados, seleciona a faixa de datas desejada e o número de ingressos. O sistema cobra uma taxa fixa por reserva bem-sucedida (ex: £10 por ingresso garantido). O pagamento só é processado após a emissão do ticket oficial (modelo baseado em sucesso).
  • API B2B para Agências de Turismo: Disponibilização de endpoints para que agências de viagens integrem a reserva automatizada de mirantes gratuitos em seus pacotes de turismo personalizados de forma invisível para o cliente final.

Tabela Comparativa: Viabilidade de Automação por Atração

Abaixo, analisamos a viabilidade técnica e comercial de automatizar as principais atrações gratuitas de Londres com base na complexidade de suas APIs e na demanda do mercado.

Atração Dificuldade da API Proteção contra Bots Janela de Reserva Potencial de Monetização
Horizon 22 Média (REST JSON) Cloudflare Turnstile Diária / Semanal Altíssimo
Sky Garden Alta (GraphQL / Custom) Akamai + Queue-it Toda segunda-feira às 9h Alto
The Lookout Baixa (Eventbrite API) Padrão Eventbrite Mensal Médio
Garden at 120 Nenhuma (Sem reserva prévia) Nenhuma (Fila física) Acesso livre Nulo

Estratégias Avançadas de Infraestrutura e Deploy Resiliente

Para operar um Micro-SaaS de automação de forma profissional, você não pode rodar scripts em sua máquina local. É necessária uma infraestrutura distribuída, tolerante a falhas e que minimize o risco de banimento de IPs.

Gerenciamento de Proxies Residenciais Rotativos

Datacenters tradicionais (AWS, DigitalOcean, Hetzner) possuem blocos de IPs conhecidos e amplamente bloqueados por WAFs. Para garantir que suas requisições de monitoramento pareçam tráfego legítimo de usuários domésticos, você deve utilizar redes de Proxies Residenciais Rotativos (como Bright Data, Oxylabs ou Smartproxy).

Esses serviços fornecem um endpoint de proxy único que, a cada requisição HTTP, encaminha o tráfego através de um dispositivo residencial real (conexões Wi-Fi domésticas, 4G/5G) em Londres. Isso torna virtualmente impossível para o Cloudflare bloquear o bot com base apenas no IP, pois o bloqueio afetaria usuários reais.

Tratamento de Erros, Idempotência e Filas de Mensageria

Quando lidamos com automação de checkout, a idempotência é crucial. Você não quer que uma falha de rede temporária faça com que o bot envie o formulário de reserva duas vezes, resultando em cobranças duplicadas ou cancelamento de ingressos por violação de termos de uso.

Utilizando o Celery com Redis como broker, podemos definir políticas rígidas de retry com backoff exponencial:

@app.task(bind=True, max_retries=3, default_retry_delay=5)
def run_booking_task(self, user_data, slot_details):
    try:
        # Executa a reserva de forma síncrona dentro do worker
        result = execute_playwright_booking(user_data, slot_details)
        return result
    except TemporaryNetworkError as exc:
        # Retenta a tarefa em caso de erro de rede temporário
        raise self.retry(exc=exc, countdown=2 ** self.request.retries)
    except HardValidationError as exc:
        # Não retenta se os dados do usuário forem inválidos
        log_error_to_sentry(exc)
        raise exc

Considerações Éticas, Termos de Serviço e o Futuro do Acesso Público

Como engenheiros de software, temos a responsabilidade de avaliar o impacto social de nossas criações. A automação de reservas de espaços públicos gratuitos caminha em uma linha tênue entre a otimização tecnológica e a exclusão social. Se todos usarem bots, o acesso aos mirantes deixará de ser democrático e passará a ser restrito àqueles que possuem conhecimento técnico ou recursos financeiros para pagar por serviços de concierge.

No entanto, a existência dessas automações expõe a fragilidade e a obsolescência dos sistemas de TI contratados pelo poder público e por grandes corporações imobiliárias. Ao expor essas vulnerabilidades de forma transparente e propor soluções de código aberto, forçamos a indústria a adotar mecanismos de autenticação mais robustos, como verificação de identidade real vinculada ao passaporte ou documento nacional, sorteios justos (lottery systems) em vez de filas por ordem de chegada, e APIs públicas oficiais que distribuam os ingressos de forma equitativa.

O desenvolvimento de ferramentas open-source de monitoramento não deve visar o monopólio de ingressos para revenda ilegal (scalping), mas sim a democratização da informação, permitindo que qualquer cidadão receba notificações em tempo real quando um espaço público de sua cidade estiver disponível para visitação.

📚 Fontes E Referências

  1. London’s Free Roof TerracesPortal Internacional

Webwright: Como o Novo Framework da Microsoft Dobrou o GPT-5.4

No dinâmico ecossistema da Inteligência Artificial, a automação de tarefas baseadas na web tem sido um dos maiores desafios de engenharia. Até recentemente, a maioria dos agentes autônomos de navegação dependia de abordagens baseadas em click-trace — sistemas que analisam visualmente a tela, mapeiam coordenadas e emulam cliques humanos de forma sequencial. Essa metodologia, embora intuitiva, é altamente frágil, lenta e propensa a falhas catastróficas diante de qualquer alteração sutil na interface do usuário (UI).

Para quebrar esse paradigma, a Microsoft Research desenvolveu e lançou o Webwright, um framework inovador nativo de terminal (terminal-native) que redefine completamente a forma como agentes de IA interagem com a web. Em vez de emular interações físicas desajeitadas, o Webwright compila as intenções do usuário diretamente em scripts reutilizáveis do Playwright. Os resultados práticos são impressionantes: operando sob o modelo GPT-5.4, o framework alcançou a marca histórica de 60,1% de sucesso no benchmark Odysseys, um salto gigantesco quando comparado aos 33,5% obtidos pelo modelo base sem o framework.

O Paradigma Terminal-Native: Por que o Click-Trace Está Obsoleto


Foto por ewirz via Pixabay

Para compreender o impacto do Webwright, é preciso entender por que as abordagens tradicionais falham em tarefas de longo horizonte (long-horizon tasks). Os agentes baseados em visão ou mapeamento de DOM direto sofrem com três problemas principais:

1. Latência e Custo Computacional

Processar capturas de tela contínuas e analisar árvores de acessibilidade gigantescas a cada passo consome uma quantidade massiva de tokens e poder de processamento. Em tarefas que exigem dezenas de passos, o custo financeiro e o tempo de execução tornam-se proibitivos para escala industrial.

2. Falta de Reutilização

Se um agente de click-trace executa uma tarefa complexa com sucesso (como extrair relatórios financeiros mensais de um sistema ERP legado), ele não gera um artefato reaproveitável. Na próxima execução, ele precisará recalcular todo o caminho visual novamente, estando sujeito a novas falhas.

3. Instabilidade de Seletores

Mudanças dinâmicas em frameworks modernos de front-end (como React ou Tailwind) frequentemente alteram IDs e classes CSS em tempo de execução. Agentes visuais perdem a referência facilmente quando confrontados com pop-ups inesperados, carregamentos assíncronos ou layouts responsivos.

O Webwright resolve essas dores ao adotar uma filosofia terminal-native. Ele opera em uma camada de abstração onde o agente de IA escreve, depura e executa código Playwright diretamente em um ambiente de terminal controlado. O resultado final não é apenas a conclusão da tarefa, mas sim um script de automação robusto, limpo e reutilizável.

A Arquitetura do Webwright: Três Módulos em um Loop de Agente Único

A genialidade do Webwright reside na sua simplicidade e eficiência de design. Com aproximadamente 1.000 linhas de código, o framework consolida um loop de agente único dividido em três módulos principais que operam de forma síncrona:

O Módulo Planejador/Gerador (Planner/Generator)

Este módulo recebe o objetivo em linguagem natural fornecido pelo usuário. Em vez de tentar adivinhar o próximo clique, o planejador analisa a estrutura geral da página web e traduz a meta em blocos de código Playwright estruturados. Ele projeta a lógica de navegação, tratamento de erros básicos e preenchimento de formulários.

O Módulo Executor (Executor)

O coração técnico do framework. O Webwright executa o script gerado em um ambiente de terminal isolado. Ele monitora a execução em tempo real, capturando logs do console, respostas de rede (APIs) e o estado final do DOM sem a necessidade de renderização visual contínua na tela do agente, o que reduz drasticamente o consumo de recursos.

O Módulo Avaliador/Refinador (Evaluator/Refiner)

Se o script falhar ou encontrar um comportamento inesperado (como um elemento não interativo), este módulo entra em ação. Ele analisa o traceback do erro do Playwright, lê o estado atual da página e reescreve o trecho de código problemático de forma autônoma. Esse ciclo de auto-depuração (self-debugging loop) é o principal fator por trás do aumento drástico nas taxas de sucesso do framework.

Exemplo Prático: Como o Webwright Opera na Prática


Foto por d97jro via Pixabay

Para ilustrar a diferença técnica, veja abaixo uma representação simplificada de como o Webwright traduz uma instrução de alto nível em um script Playwright resiliente e auto-corrigível, pronto para rodar no terminal:

# Exemplo de fluxo de geração e execução do Webwright
import asyncio
from playwright.async_api import async_playwright

async def webwright_agent_task():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        
        try:
            # Instrução: 'Acesse o portal de relatórios, faça login e extraia o PDF mensal'
            await page.goto("https://exemplo-portal.com/login")
            
            # O Webwright prioriza seletores semânticos e robustos para evitar quebras
            await page.get_by_placeholder("Digite seu e-mail").fill("usuario@empresa.com")
            await page.get_by_role("button", name="Continuar").click()
            
            # Tratamento dinâmico de carregamento assíncrono
            await page.wait_for_selector(".dashboard-content", timeout=5000)
            
            # Download seguro do relatório
            async with page.expect_download() as download_info:
                await page.get_by_role("link", name="Baixar PDF Mensal").click()
            download = await download_info.value
            await download.save_as("./relatorios/mensal.pdf")
            print("[Webwright Success] Script executado e salvo com sucesso.")
            
        except Exception as e:
            # O módulo avaliador captura o erro e inicia o ciclo de refinamento
            print(f"[Webwright Refiner] Erro detectado: {str(e)}")
            # Aqui, o agente reanalisaria o DOM e geraria um patch de código em tempo real
            
        finally:
            await browser.close()

asyncio.run(webwright_agent_task())

Análise de Performance: Quebrando Recordes nos Benchmarks Odysseys e Mind2Web

A eficácia do Webwright foi validada através de testes rigorosos em alguns dos benchmarks mais complexos do setor de agentes autônomos. Os resultados demonstram que a abordagem de compilação de código supera sistematicamente a execução direta de modelos de linguagem.

Métrica / Benchmark GPT-5.4 (Base) Webwright + GPT-5.4 Melhoria Absoluta
Odysseys Benchmark (Tarefas de Longo Horizonte) 33.5% 60.1% +26.6%
Online-Mind2Web (AutoEval Score) 54.2% 86.7% +32.5%

O benchmark Odysseys é conhecido por simular ambientes de navegação complexos do mundo real, exigindo que o agente tome dezenas de decisões sequenciais, lide com autenticação multifator simulada, navegue por menus aninhados e recupere informações profundas. O salto de 33,5% para 60,1% mostra que a habilidade de depurar o próprio código no terminal dá ao agente uma resiliência sem precedentes.

No Online-Mind2Web, a pontuação de 86,7% representa o score mais alto de AutoEval registrado entre todas as receitas de harness de código aberto disponíveis atualmente no mercado.

Por que a Execução Headless e Local é o Futuro dos Negócios

Para empresas que buscam implementar automação de processos de negócios (BPA) baseada em inteligência artificial, o Webwright oferece vantagens competitivas claras:

Segurança e Governança

Como o framework é nativo de terminal e gera scripts Playwright puros, toda a execução pode ser auditada linha por linha antes de ser promovida para ambientes de produção. Isso elimina o risco de comportamentos imprevisíveis comuns em agentes visuais que tomam decisões em tempo real diretamente na interface gráfica.

Integração CI/CD Facilitada

Scripts gerados pelo Webwright podem ser facilmente integrados a pipelines de integração e entrega contínuas (CI/CD), rodando em containers Docker leves, sem a necessidade de infraestruturas pesadas de virtualização de desktop (VDI).

Eficiência Operacional

A automação baseada em código consome uma fração da largura de banda e do processamento de CPU necessários para rodar navegadores com renderização visual completa. Isso se traduz em uma redução direta nos custos de infraestrutura em nuvem.

Conclusão e Próximos Passos

O lançamento do Webwright pela Microsoft Research marca um divisor de águas na evolução dos agentes web. Ao trocar a fragilidade das interações visuais baseadas em coordenadas pela solidez e reutilização de código Playwright gerado dinamicamente, o framework abre caminho para automações corporativas verdadeiramente confiáveis e escaláveis.

À medida que os modelos de linguagem avançam, frameworks focados em compilação de código e execução local, como o Webwright, se consolidarão como o padrão ouro para a integração entre inteligência artificial e sistemas legados baseados na web.

As informações originais detalhadas sobre o lançamento e a arquitetura técnica do framework podem ser acessadas diretamente no Artigo de Origem.

Sair da versão mobile