🎯 Um navegador em nuvem personalizável e anti-detecção alimentado por Chromium desenvolvido internamente, projetado para rastreadores web e agentes de IA. 👉Experimente agora
De volta ao blog

Como Extrair localStorage Com Playwright e Scrapeless

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

30-Jul-2026

Um navegador pode manter um estado útil da página fora do DOM. Este guia usa o Playwright para inspecionar o localStorage em uma demonstração pública do MDN, alterar três preferências reais pela interface do usuário, capturar os eventos de armazenamento resultantes em uma segunda aba e provar que os valores sobrevivem a um recarregamento antes de mover a mesma lógica para o Scrapeless Scraping Browser.

O que o Armazenamento Web Adiciona a um Fluxo de Trabalho de Scraping

A API de Armazenamento Web oferece a uma origem duas lojas com chave de string:

  • localStorage é compartilhado por documentos da mesma origem e sobrevive a recarregamentos de página comuns e reinicializações do navegador quando o perfil é persistente.
  • sessionStorage é limitado a um contexto de navegação de nível superior e dura durante aquela sessão de página.

Nenhuma das lojas é um pote de cookies. Os valores de Armazenamento Web não estão anexados automaticamente a solicitações HTTP, e cada chave/valor é uma string. O guia da API de Armazenamento Web do MDN define esses limites de escopo e persistência.

Para scraping, o armazenamento pode conter preferências da interface do usuário, identificadores em cache, estado de recursos ou dados públicos que o aplicativo já carregou. Trate-o como estado do navegador a ser validado, não como uma razão para coletar tokens de autenticação ou dados privados do usuário.

Por que Usar Playwright com Scrapeless

O Playwright pode avaliar JavaScript na origem da página, abrir duas páginas no mesmo BrowserContext e observar o evento de armazenamento do próprio navegador. O Scrapeless Scraping Browser fornece uma sessão Chromium hospedada, mantendo essas APIs do Playwright.

A conexão do navegador utiliza connect_over_cdp. Uma vez que uma page existe, a inspeção de armazenamento é a mesma, seja o Chromium local ou hospedado.

Pré-requisitos

  • Python 3.10 ou posterior.
  • playwright 1.59.0 ou uma versão compatível atual.
  • Chrome/Chromium local para o exemplo executável completo.
  • Uma conta Scrapeless financiada e SCRAPELESS_API_KEY para a conexão em nuvem. Novas sessões de navegador na conta de verificação retornaram o código 14500, portanto, o bloco de conexão é uma lacuna explícita de pré-requisito.

Instalação

bash Copy
python -m pip install "playwright==1.59.0"

Conectar ao Scrapeless Scraping Browser

Nota: Este bloco requer saldo financiado no Scraping Browser. A conta de verificação final retornou saldo insuficiente, por favor recarregue primeiro. Execute com sua própria chave financiada; o fluxo completo de armazenamento abaixo rodou no Chrome local contra a mesma página pública.

python Copy
import os
from urllib.parse import urlencode
from playwright.sync_api import sync_playwright

params = urlencode({
    "token": os.environ["SCRAPELESS_API_KEY"],
    "sessionTTL": 120,
    "proxyCountry": "US",
})
cdp_url = f"wss://browser.scrapeless.com/api/v2/browser?{params}"

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(cdp_url)
    context = browser.contexts[0]
    page = context.pages[0]
    # Execute os passos de armazenamento abaixo com contexto e página.
    browser.close()

Use a documentação de desenvolvedor do Scrapeless para parâmetros de conexão atuais.

Inspecionar Cada Chave do localStorage

A demonstração pública do MDN armazena uma cor de fundo, fonte e escolha de imagem:

python Copy
TARGET_URL = "https://mdn.github.io/dom-examples/web-storage/"

page.goto(TARGET_URL, wait_until="domcontentloaded")
stored = page.evaluate(
    "Object.fromEntries(Object.entries(localStorage))"
)
print("armazenamento inicial:", stored)
print("armazenamento de sessão:", page.evaluate("sessionStorage.length"))
text Copy
armazenamento inicial: {'font': 'sans-serif', 'image': 'images/firefoxos.png', 'bgcolor': 'FF0000'}
armazenamento de sessão: 0

Ler todas as entradas evita restringir o extrator a uma chave. Mantenha a origem na saída porque o mesmo nome de chave pode significar algo diferente em outro site.

Capturar Alterações em uma Segunda Aba

O storage evento é disparado em outros documentos da mesma origem que compartilham a loja alterada. Ele não é disparado na aba que fez a mudança.

python Copy
observer_page = context.new_page()
observer_page.goto(TARGET_URL, wait_until="domcontentloaded")
observer_page.evaluate("""
    window.capturedStorageEvents = [];
    addEventListener('storage', event => {
        capturedStorageEvents.push({
            key: event.key,
            oldValue: event.oldValue,
            newValue: event.newValue,
        });
    });
""")

Ambas as páginas devem compartilhar um contexto e origem do navegador. Um segundo contexto tem armazenamento separado e não receberá esses eventos.

Alterar Controles Reais da Interface do Usuário

Altere os controles da demonstração em vez de escrever as chaves diretamente:

python Copy
page.evaluate("""
    bgcolor.value = '00FF00';
    bgcolor.dispatchEvent(new Event('change', {bubbles: true}));
""")
page.select_option("#font", "serif")
page.select_option("#image", "images/crocodile.png")
page.wait_for_timeout(500)

print("armazenamento atualizado:", page.evaluate(
    "Object.fromEntries(Object.entries(localStorage))"
))
print("eventos:", observer_page.evaluate("capturedStorageEvents"))
text Copy
armazenamento atualizado: {'font': 'serif', 'image': 'images/crocodile.png', 'bgcolor': '00FF00'}
eventos: [{'key': 'bgcolor', 'oldValue': 'FF0000', 'newValue': '00FF00'}, {'key': 'font', 'oldValue': 'sans-serif', 'newValue': 'serif'}, {'key': 'image', 'oldValue': 'images/firefoxos.png', 'newValue': 'images/crocodile.png'}]

Essa saída prova três coisas ao mesmo tempo: a interface do usuário escreveu no armazenamento, a segunda aba recebeu exatamente três alterações e cada evento preservou seu valor anterior.

Pronto para inspecionar o estado em uma sessão hospedada? Crie uma conta gratuita no Scrapeless e substitua apenas a criação do navegador.

Prove que os Valores Sobrevivem ao Recarregamento

python Copy
page.reload(wait_until="domcontentloaded")
reloaded = page.evaluate(
    "Object.fromEntries(Object.entries(localStorage))"
)
controls = {
    "bgcolor": page.locator("#bgcolor").input_value(),
    "font": page.locator("#font").input_value(),
    "image": page.locator("#image").input_value(),
}

print("armazenamento recarregado:", reloaded)
print("valores dos controles:", controls)
text Copy
armazenamento recarregado: {'font': 'serif', 'image': 'images/crocodile.png', 'bgcolor': '00FF00'}
valores dos controles: {'bgcolor': '00FF00', 'font': 'serif', 'image': 'images/crocodile.png'}

Combinar os controles visíveis com o estado armazenado é mais forte do que verificar apenas o armazenamento. Isso prova que a aplicação consumiu os valores salvos após a navegação.

Script Executável Completo

python Copy
from playwright.sync_api import sync_playwright

TARGET_URL = "https://mdn.github.io/dom-examples/web-storage/"

with sync_playwright() as p:
    browser = p.chromium.launch(
        executable_path="/usr/bin/google-chrome",
        headless=True,
    )
    context = browser.new_context()
    page = context.new_page()
    observer_page = context.new_page()

    observer_page.goto(TARGET_URL, wait_until="domcontentloaded")
    observer_page.evaluate("""
        window.capturedStorageEvents = [];
        addEventListener('storage', event => {
            capturedStorageEvents.push({
                key: event.key,
                oldValue: event.oldValue,
                newValue: event.newValue,
            });
        });
    """)
    page.goto(TARGET_URL, wait_until="domcontentloaded")

    initial = page.evaluate(
        "Object.fromEntries(Object.entries(localStorage))"
    )
    page.evaluate("""
        bgcolor.value = '00FF00';
        bgcolor.dispatchEvent(new Event('change', {bubbles: true}));
    """)
    page.select_option("#font", "serif")
    page.select_option("#image", "images/crocodile.png")
    page.wait_for_timeout(500)

    updated = page.evaluate(
        "Object.fromEntries(Object.entries(localStorage))"
    )
    events = observer_page.evaluate("capturedStorageEvents")
    page.reload(wait_until="domcontentloaded")
    reloaded = page.evaluate(
        "Object.fromEntries(Object.entries(localStorage))"
    )
    controls = {
        "bgcolor": page.locator("#bgcolor").input_value(),
        "font": page.locator("#font").input_value(),
        "image": page.locator("#image").input_value(),
    }

    assert len(events) == 3
    assert updated == reloaded == controls
    assert page.evaluate("sessionStorage.length") == 0

    print("título:", page.title())
    print("armazenamento inicial:", initial)
    print("armazenamento atualizado:", updated)
    print("chaves dos eventos:", [event["key"] for event in events])
    print("contagem de eventos:", len(events))
    print("armazenamento recarregado:", reloaded)
    print("valores dos controles:", controls)
    print("entradas do armazenamento de sessão:", page.evaluate("sessionStorage.length"))
    browser.close()

A execução retorna três chaves iniciais, três chaves atualizadas, três eventos entre abas, controles recarregados correspondentes e zero entradas de sessionStorage.

localStorage, sessionStorage e Cookies

localStorage

Compartilhado por documentos da mesma origem, apenas string e persistente até ser limpo. Use-o quando a aplicação manter deliberadamente o estado entre visitas.

sessionStorage

Separado para cada sessão de página de nível superior. Duplicar ou abrir uma aba pode criar um ciclo de vida distinto mesmo na mesma origem. Inspecione-o a partir da exata página cujo estado importa.

Cookies

Enviados com solicitações HTTP correspondentes de acordo com as regras de cookies. Use as APIs de cookies do contexto do Playwright em vez de confundi-los com o armazenamento web.

Limites de Extração Segura

O armazenamento pode conter credenciais, identificadores de usuário ou estado privado. Restringa os exemplos a páginas de demonstração públicas, colete apenas os campos necessários para a tarefa declarada e nunca publique tokens ou material de sessão. O acesso de origem através de um navegador não concede permissão para reutilizar todos os valores que você pode ler.

Conclusão

A extração de Web Storage é útil quando o navegador tem um estado que o DOM visível sozinho não consegue explicar. Leia o mapa completo, mantenha a origem com o registro, observe mudanças entre abas quando precisar de proveniência e verifique se a aplicação consome valores armazenados após navegação. Mover o fluxo de trabalho para o Scrapeless muda a conexão do navegador, não a lógica de armazenamento.

Comece com o Scrapeless, revise os preços do Scrapeless e leia o que o CDP expõe antes de mover sessões com estado para a nuvem.

FAQ

Q: O Playwright pode ler localStorage?

Sim. Avalie Object.fromEntries(Object.entries(localStorage)) dentro de uma página na origem alvo.

Q: Por que não usar context.storage_state() para tudo?

O estado de armazenamento é útil para exportar estados de autenticação suportados, mas a avaliação direta de páginas permite que você inspecione o mapa de chaves ao vivo e o correlacione com alterações na interface do usuário e eventos de armazenamento.

Q: O localStorage sobrevive a um recarregamento?

Sim, a menos que a aplicação ou o navegador limpe. Os três valores alterados da demonstração do MDN sobreviveram ao recarregamento testado e repopularam os controles.

Q: A aba que altera o localStorage recebe um evento de armazenamento?

Não. O evento é entregue a outros documentos de mesma origem que compartilham o armazenamento, razão pela qual o exemplo escuta em uma segunda página.

Q: O sessionStorage é compartilhado entre abas?

Não. Ele é limitado a um contexto de navegação de nível superior e seus contextos filhos de mesma origem, portanto, inspecione-o a partir da sessão da página específica.

Q: Os valores de Web Storage são sempre JSON?

Não. Cada valor é armazenado como uma string. Analise JSON apenas quando o formato da aplicação estiver confirmado e trate JSON inválido explicitamente.

Q: É seguro raspar o armazenamento do navegador?

Apenas dentro das permissões do alvo e das suas obrigações de manuseio de dados. Evite credenciais e estado privado do usuário, mantenha a coleta limitada e revise os termos do site e a política de robots, quando aplicável.

Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.

Artigos mais populares

Catálogo