Como Raspagem de Iframes Com Playwright e Scrapeless
Senior Web Scraping Engineer
TL;DR:
- Um iframe contém um documento separado que os seletores da página pai não conseguem pesquisar. Selecione o quadro filho antes de localizar ou extrair seus elementos.
- O Playwright expõe cada contexto de navegação através de
page.frames. Identifique o filho pretendido por um nome estável, padrão de URL ou elemento iframe proprietário em vez de confiar na posição do array. FrameeFrameLocatoratendem a necessidades de extração diferentes. UseFramepara controle de metadados e ciclo de vida; useFrameLocatorpara ações concisas em elementos.- O Playwright pode automatizar o conteúdo de iframe de diferentes origens através do protocolo do navegador. O JavaScript na página permanece sujeito à política de mesma origem do navegador.
- A mesma lógica de extração de iframe funciona localmente e através do Scrapeless. Mover para o Scrapeless Scraping Browser altera a criação do navegador, não a seleção de quadro ou o código do localizador.
- Grátis para começar. Novas contas do Scrapeless incluem tempo de execução gratuito do Scraping Browser—inscreva-se em app.scrapeless.com.
Introdução: Comece Com o Documento Certo
Um iframe é um documento separado com sua própria URL, ciclo de vida e DOM. Este guia usa o Playwright para enumerar os contextos de navegação em uma página real, identifica o filho pretendido pelo nome e URL, e extrai um formulário que um seletor da página pai não pode ver. A mesma lógica de quadro é executada após conectar o Playwright ao Scrapeless Scraping Browser.
Por Que Iframes Precisam de um Caminho de Extração Diferente
Um <iframe> incorpora outro contexto de navegação dentro da página pai. O elemento pertence ao DOM pai; o documento carregado pertence a um quadro filho. Um seletor avaliado contra a página pai não pesquisa esse documento filho.
A referência HTML de iframe descreve esse contexto aninhado e seu próprio histórico de sessão. O Playwright expõe cada contexto como um Frame, enquanto FrameLocator oferece uma maneira concisa de localizar elementos através do elemento <iframe>.
Por Que Usar Playwright Com Scrapeless
O Playwright pode inspecionar metadados de quadros e interagir com um documento filho, mesmo quando o iframe é de diferentes origens. Esse acesso ao nível do navegador difere do JavaScript em execução dentro da página pai, que está restrito pela política de mesma origem.
O Scrapeless Scraping Browser move o Chromium para um ambiente hospedado de anti-detecção enquanto mantém as APIs de quadros do Playwright. A conexão usa connect_over_cdp; cada linha de extração após a criação do navegador permanece padrão do Playwright.
Pré-requisitos
- Python 3.10 ou superior.
playwright1.59.0 ou uma versão compatível atual.- Chrome/Chromium local para a completa queda executável.
- Uma conta Scrapeless financiada e
SCRAPELESS_API_KEYpara a conexão do navegador em nuvem. Novas sessões na conta de verificação retornaram código 14500, então a conexão em nuvem é uma lacuna de pré-requisito rotulada.
Instalar
bash
python -m pip install "playwright==1.59.0"
O exemplo executável usa o /usr/bin/google-chrome do host. Use um Chromium gerenciado pelo Playwright se for assim que seu projeto provisiona navegadores.
Conectar ao Scrapeless Scraping Browser
Nota: Essa conexão precisa de saldo financiado no Scraping Browser. A conta de verificação final retornou
saldo insuficiente, por favor reabasteça primeiro. Use sua própria chave financiada; a enumeração de quadros e a extração abaixo foram executadas completamente no Chrome local.
python
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)
page = browser.contexts[0].pages[0]
# Continue com os passos do quadro abaixo.
browser.close()
Use a documentação do desenvolvedor do Scrapeless para os parâmetros de conexão atuais.
Passo 1 — Abra uma Página Com um Quadro Filho Conhecido
O Selenium mantém um pequeno fixture de teste público. Sua página pai tem um iframe nomeado iframe1-name, cujo src carrega formPage.html:
python
TARGET_URL = "https://www.selenium.dev/selenium/web/iframes.html"
page.goto(TARGET_URL, wait_until="domcontentloaded")
page.wait_for_selector("#iframe1")
page.wait_for_timeout(500)
print("título da página pai:", page.title())
print("e-mail da página pai corresponde:", page.locator("#email").count())
text
título da página pai: Esta página tem iframes
e-mail da página pai corresponde: 0
O campo de entrada de e-mail existe, mas pertence ao documento do formulário incorporado em vez do pai.
Passo 2 — Enumerar Frames Antes de Selecionar Um
page.frames contém o frame principal mais cada filho e descendente anexado:
python
print("contagem de frames:", len(page.frames))
for index, frame in enumerate(page.frames):
print(index, repr(frame.name), frame.url, frame.title())
text
contagem de frames: 2
0 '' https://www.selenium.dev/selenium/web/iframes.html Esta página tem iframes
1 'iframe1-name' https://www.selenium.dev/selenium/web/formPage.html Nós Saímos Daqui
O índice zero é o documento principal. Não transforme o índice um em um contrato permanente: outro anúncio, widget de consentimento ou frame de análise pode alterar a ordem. Nome e URL são evidências melhores.
Passo 3 — Selecionar o Frame pelo Nome ou URL
A fixture fornece sinais estáveis:
python
named_frame = page.frame(name="iframe1-name")
url_frame = next(
frame for frame in page.frames
if frame.url.endswith("/formPage.html")
)
assert named_frame is url_frame
print("frame selecionado:", url_frame.name)
print("título selecionado:", url_frame.title())
Se os nomes forem gerados, combine um padrão de URL delimitado ou encontre o elemento iframe proprietário e chame content_frame(). Falhe quando mais de um candidato corresponder; escolher silenciosamente o primeiro duplicado produz dados plausíveis do widget errado.
Passo 4 — Extrair Dados do Documento Filho
Uma vez que você possui o Frame, sua API de localizador se comporta como a da página:
python
email = url_frame.locator("#email")
selected = url_frame.locator("#multi option:checked").evaluate_all(
"options => options.map(option => option.value)"
)
record = {
"frame_name": url_frame.name,
"frame_url": url_frame.url,
"frame_title": url_frame.title(),
"email_inputs": email.count(),
"selected_values": selected,
}
print("entradas de e-mail:", record["email_inputs"])
print("valores selecionados:", record["selected_values"])
text
entradas de e-mail: 1
valores selecionados: ['ovos', 'salsichas']
A página filho possui um campo de seleção múltipla com essas duas opções selecionadas em sua fonte. Esta é uma verificação mais forte do que ler apenas um cabeçalho: prova que o Playwright alcançou o documento do formulário e avaliou o estado dentro dele.
Passo 5 — Usar FrameLocator para Ações Diretas
Quando você não precisa de metadados do frame, o FrameLocator é mais curto:
python
frame_ui = page.frame_locator("#iframe1")
print("e-mail através do FrameLocator:", frame_ui.locator("#email").count())
O guia oficial de frames do Playwright mostra os mesmos dois níveis: localizar conteúdo através de um elemento iframe, ou obter um objeto Frame por URL/nome.
Pronto para executar esses localizadores em um navegador hospedado? Crie uma conta Scrapeless gratuita e substitua apenas a criação do navegador.
Script de Verificação Local Completo
python
from playwright.sync_api import sync_playwright
TARGET_URL = "https://www.selenium.dev/selenium/web/iframes.html"
with sync_playwright() as p:
browser = p.chromium.launch(
executable_path="/usr/bin/google-chrome",
headless=True,
)
page = browser.new_page()
page.goto(TARGET_URL, wait_until="domcontentloaded")
page.wait_for_selector("#iframe1")
page.wait_for_timeout(500)
child = next(
frame for frame in page.frames
if frame.url.endswith("/formPage.html")
)
selected = child.locator("#multi option:checked").evaluate_all(
"options => options.map(option => option.value)"
)
frame_locator_count = page.frame_locator("#iframe1").locator("#email").count()
assert page.locator("#email").count() == 0
assert child.name == "iframe1-name"
assert child.locator("#email").count() == 1
assert selected == ["ovos", "salsichas"]
assert frame_locator_count == 1
print("título pai:", page.title())
print("correspondências de e-mail pai:", page.locator("#email").count())
print("contagem de frames:", len(page.frames))
print("nome filho:", child.name)
print("URL do filho:", child.url)
print("título do filho:", child.title())
print("correspondências de e-mail filho:", child.locator("#email").count())
print("valores selecionados:", selected)
print("correspondências de e-mail do FrameLocator:", frame_locator_count)
browser.close()
A execução completa retorna dois frames, zero correspondências de e-mail no pai, uma correspondência de e-mail no filho, o nome/título/URL do frame esperado e ['ovos', 'salsichas'] do formulário filho.
O Que Você Recebe de Volta
O fluxo de trabalho verificado retorna tanto o estado do formulário extraído quanto metadados de frame suficientes para identificar sua fonte:
json
{
"correspondências_de_email_pai": 0,
"contagem_de_frames": 2,
"nome_do_frame": "iframe1-name",
"url_do_frame": "https://www.selenium.dev/selenium/web/formPage.html",
"título_do_frame": "Nós Saímos Daqui",
"correspondências_de_email_filho": 1,
}
"selected_values": ["ovos", "salsichas"]
}
A saída estabelece quatro fatos: o documento pai não pode ver o campo de e-mail, o filho pretendido é identificável pelo nome e URL, o localizador do filho encontra uma entrada correspondente e os valores do formulário selecionados vêm de dentro desse quadro. Mantenha o nome do quadro e o URL com cada registro extraído quando uma página contém vários documentos incorporados.
Iframes de Origem Cruzada e a Política de Mesmo Origem
JavaScript do navegador, como document.querySelector("iframe").contentDocument, pode ser bloqueado quando as origens pai e filho diferem. O Playwright se comunica com o protocolo de automação do navegador e expõe o filho como um Frame, para que possa localizar e interagir com elementos em documentos de origem cruzada.
Isso não remove todos os limites. Atributos de sandbox podem restringir scripts, a navegação pode substituir um quadro enquanto você o está lendo e extensões de navegador ou visualizadores de PDF podem não expor um documento HTML comum. Inspecione a árvore do quadro real antes de redigir o contrato de extração.
Frames Dinâmicos e Aninhados
Aguarde a anexação e navegação
Um elemento iframe pode aparecer antes que seu filho tenha alcançado a URL final. Aguarde um localizador de filho ou inspecione eventos de navegação do quadro; o marcador de prontidão útil é o elemento que contém os dados, e não meramente a tag <iframe> pai.
Espere a desanexação
Aplicativos de uma única página às vezes removem e recriam iframes. Um objeto Frame salvo pode ficar desanexado. Resolva o quadro novamente a partir de seu nome estável, URL ou elemento proprietário após a transição da UI, em vez de supor que o objeto antigo sobrevive.
Percorra quadros aninhados deliberadamente
Para contextos aninhados, inspecione frame.child_frames ou encadeie FrameLocators. Mantenha o caminho pai-filho na proveniência da saída para que dois widgets com o mesmo nome não possam ser confundidos.
Conclusão
A extração de iframes começa escolhendo o documento certo. Enumere a árvore do quadro, selecione o filho por nome ou URL estável, aguarde um elemento dentro dele e mantenha os metadados do quadro com o registro extraído. Use FrameLocator para ações concisas e objetos Frame quando precisar de identidade, navegação ou controle de quadros aninhados. Mover o fluxo de trabalho para o Scrapeless altera a criação do navegador, não a lógica do quadro.
Pronto para Extrair Dados de Iframes?
Junte-se a desenvolvedores que estão criando fluxos de trabalho de extração baseados em navegador na comunidade Scrapeless: Discord · Telegram.
Comece com Scrapeless, revise preços do Scrapeless, e leia o que CDP expõe antes de mover o mesmo fluxo de trabalho de quadro para um navegador hospedado.
FAQ
Q: Por que a página pai não consegue encontrar um elemento dentro de um iframe?
O iframe possui um documento separado. Localizadores da página pai buscam no contexto de navegação pai; selecione o Frame filho ou use um FrameLocator primeiro.
Q: Devo selecionar um quadro pelo índice do array?
Não. A ordem dos quadros muda quando as páginas adicionam widgets ou anúncios. Prefira um nome estável, padrão de URL ou elemento iframe proprietário e falhe em correspondências ambíguas.
Q: Qual é a diferença entre Frame e FrameLocator?
Um Frame expõe identidade do documento, URL, nome, ciclo de vida e frames filhos. FrameLocator fornece operações de localização concisas através de um elemento iframe específico.
Q: O Playwright pode acessar um iframe de origem cruzada?
Sim, o Playwright pode automatizar filhos de quadros de origem cruzada através do protocolo do navegador, mesmo quando o JavaScript da página não consegue ler contentDocument por causa da política de mesmo origem.
Q: Como espero por um iframe carregado dinamicamente?
Aguarde um localizador que contenha dados dentro do quadro ou uma URL de quadro final conhecida. A presença do elemento iframe sozinha não prova que seu documento filho terminou de navegar.
Q: O que acontece se o quadro for desanexado?
O Frame salvo não representa mais um documento ativo. Resolva o quadro de substituição novamente a partir de evidências estáveis após a transição da página.
Q: A extração de iframes é legal?
A incorporação não muda os direitos ou termos de dados do destino. Revise as políticas do site e do fornecedor incorporado, respeite diretivas de robots quando aplicável, mantenha o volume limitado e busque aconselhamento jurídico para coleta sensível ou comercial.
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.



