🎯 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

MechanicalSoup: Automatize a Extração de Dados Baseada em Formulários em Python

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

29-Jun-2026

TL;DR:

  • MechanicalSoup automatiza sites com formulários ao emparelhar requests com BeautifulSoup. Um objeto StatefulBrowser abre uma página, seleciona um formulário, preenche seus campos, o submete e analisa a resposta — sem processo de navegador e sem engine JavaScript.
  • O navegador mantém cookies e estado de sessão entre requisições para você. Após um login ou um Set-Cookie, o mesmo StatefulBrowser envia o cookie armazenado de volta em cada requisição posterior, fazendo com que fluxos multi-etapas se comportem como uma sessão real.
  • select_form mais atribuição de campo estilo dicionário é toda a superfície da API. Você direciona um formulário por seletor CSS, define browser["nome_do_campo"] = valor, e chama submit_selected() — a biblioteca cuida da codificação e do redirecionamento.
  • MechanicalSoup lê apenas o HTML que o servidor retorna — não executa JavaScript. Uma página que constrói seu conteúdo do lado do cliente retorna vazia, porque não há etapa de renderização do DOM entre a resposta HTTP e o BeautifulSoup.
  • Quando uma página precisa de renderização ou ativa um desafio para bots, passe a busca ao Scrapeless Scraping Browser e continue analisando com BeautifulSoup. O SDK do Scrapeless cria uma sessão na nuvem, o Playwright a controla via CDP para executar o JavaScript, e o HTML renderizado retorna diretamente para os mesmos seletores soup.select(...).
  • Gratuito para começar. Novas contas Scrapeless incluem tempo de execução gratuito do Scraping Browser — inscreva-se em app.scrapeless.com.

Introdução: os formulários ainda são onde a maior parte do trabalho de scraping se esconde

Uma grande parte dos dados úteis está atrás de um formulário — uma caixa de pesquisa, um login, um painel de filtros, um assistente de múltiplas páginas. MechanicalSoup existe exatamente para esse tipo de site. Ele envolve a biblioteca HTTP requests e o BeautifulSoup em um único objeto de navegador com estado: busca uma página, permite que você preencha e submeta formulários HTML nela, segue o redirecionamento e analisa o que voltar. Sem Selenium, sem Chromium, sem binário do driver.

O minimalismo mantém a velocidade e também estabelece um limite claro sobre o que a biblioteca pode acessar. MechanicalSoup fala semântica HTTP e analisa HTML. Ele nunca executa o JavaScript da página, então qualquer coisa renderizada do lado do cliente — um feed de rolagem infinita, uma lista de resultados React, uma caixa de pesquisa que busca resultados via XHR — retorna como a casca vazia que o servidor enviou inicialmente. Ele continua rápido em um formulário renderizado pelo servidor e fica cego em um renderizado pelo cliente.

Este guia percorre um fluxo de trabalho real do MechanicalSoup do início ao fim — instalar, abrir uma página, preencher e submeter um formulário, carregar cookies ao longo de uma sessão e extrair os resultados — e então mostra o limite honesto. Quando um alvo é renderizado no navegador ou está atrás de um desafio anti-bot ativo, a busca é transferida para o Scrapeless Scraping Browser através do Protocolo de Ferramentas de Desenvolvimento do Chrome, enquanto seu código de análise com BeautifulSoup permanece exatamente como estava.


O Que Você Pode Fazer Com Isso

  • Submeter formulários de login e manter a autenticação. Preencha os campos de nome de usuário e senha, submeta, e o StatefulBrowser mantém os cookies de sessão para cada página depois disso.
  • Dirigir formulários de busca e filtro. Defina um campo de consulta, submeta e analise as linhas de resultado que o servidor retorna — o clássico loop de busca e scraping.
  • Percorrer fluxos de múltiplas páginas. Siga links e submeta formulários sucessivos em um único objeto de navegador, com o jarro de cookies e o referer transportados automaticamente.
  • Ler tabelas e listas renderizadas pelo servidor. Qualquer coisa presente no HTML bruto — tabelas de preços, listagens, páginas de diretório — está a um soup.select() de distância.
  • Scriptar envios repetitivos. Execute novamente o mesmo formulário com diferentes valores de campo para varrer um catálogo de consultas sem tocar em um navegador real.

Por Que Scrapeless Scraping Browser

O Scrapeless Scraping Browser é um navegador em nuvem personalizável, projetado para web crawlers e agentes de IA. Para as páginas que o MechanicalSoup não consegue acessar por conta própria, ele traz:

  • Renderização de JavaScript do lado da nuvem — os scripts da página são executados no navegador remoto, então o conteúdo construído pelo cliente existe no HTML quando você o analisa.
  • Proxies residenciais em mais de 195 países — prenda a saída com proxy_country para que páginas geograficamente bloqueadas e formulários limitados à região sirvam o conteúdo que serviriam a um visitante local.
  • Fingerprinting anti-detekção — a sessão se apresenta como um navegador real, então a página de formulário ou resultado é renderizada em vez de retornar um desafio intersticial.
  • Persistência de sessão — cookies e estado de autenticação permanecem ativos durante as navegações dentro de uma sessão, a mesma propriedade que o MechanicalSoup oferece localmente.
  • Um endpoint CDP padrãobrowser_ws_endpoint é uma URL WebSocket comum, então o Playwright (ou qualquer cliente CDP) se conecta com uma chamada e seu código de análise permanece inalterado.

Obtenha sua chave de API no plano gratuito em app.scrapeless.com.


Pré-requisitos

  • Python 3.10 ou mais recente
  • Uma conta Scrapeless e chave de API — inscreva-se em app.scrapeless.com (somente necessário para a seção do navegador em nuvem)
  • Familiaridade básica com seletores CSS e o terminal

Instalação

MechanicalSoup é um único pacote que inclui requests e beautifulsoup4 como dependências:

bash Copy
pip install mechanicalsoup

Confirme a instalação e a versão:

bash Copy
python -c "import mechanicalsoup; print(mechanicalsoup.__version__)"
# 1.4.0

Configurar: abrir uma página com um StatefulBrowser

Tudo no MechanicalSoup é executado através de um StatefulBrowser. Ele mantém a página atual, a sessão e o jar de cookies. Defina um agente de usuário na construção para que as solicitações carreguem uma identidade sensata:

python Copy
import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser(
    user_agent="Mozilla/5.0 (compatible; data-collector)"
)

browser.open("https://httpbingo.org/forms/post")
# browser.page agora é um objeto BeautifulSoup que você pode consultar diretamente

browser.open() retorna a resposta requests; browser.page é a árvore BeautifulSoup analisada para a página que você acabou de carregar.


Implementação básica: preencher e enviar um formulário

O loop principal consiste em três chamadas — selecionar o formulário, atribuir seus campos, enviar. select_form recebe um seletor CSS; a atribuição de campos é feita no estilo dicionário no navegador; submit_selected() posta o formulário e segue o redirecionamento.

python Copy
import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser(
    user_agent="Mozilla/5.0 (compatible; data-collector)"
)
browser.open("https://httpbingo.org/forms/post")

# Alvo o formulário pela sua ação, depois preencho campos pelo nome
browser.select_form('form[action="/post"]')
browser["custname"] = "Ada Lovelace"
browser["custtel"] = "555-0100"
browser["custemail"] = "ada@example.com"
browser["size"] = "medium"             # botão de rádio
browser["topping"] = ["bacon", "cheese"]  # caixas de seleção de múltiplos valores
browser["comments"] = "Deixar na porta"

response = browser.submit_selected()
print(response.status_code)
data = response.json()
print(data["url"])
print(data["form"])

O endpoint httpbin ecoa o corpo do formulário analisado, que confirma exatamente o que o MechanicalSoup enviou:

json Copy
{
  "url": "https://httpbingo.org/post",
  "form": {
    "comments": "Deixar na porta",
    "custemail": "ada@example.com",
    "custname": "Ada Lovelace",
    "custtel": "555-0100",
    "delivery": "",
    "size": "medium",
    "topping": ["bacon", "cheese"]
  }
}
// Os valores refletem a submissão real; o "delivery" vazio é um campo não definido no formulário.

Botões de rádio aceitam uma única string, grupos de caixas de seleção aceitam uma lista, e qualquer campo deixado não definido é enviado vazio — a mesma codificação que um navegador produziria.


Padrões avançados

Carregar cookies através de uma sessão

Um StatefulBrowser reutiliza uma única requests.Session, então qualquer cookie que o servidor define persiste para solicitações futuras automaticamente. É isso que faz os logins e fluxos de vários passos funcionarem:

python Copy
import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser()

# O servidor define um cookie nesta solicitação
browser.open("https://httpbingo.org/cookies/set?session_id=abc123")
print(browser.session.cookies.get_dict())
# {'session_id': 'abc123'}

# Uma solicitação posterior no mesmo navegador envia o cookie armazenado de volta
echo = browser.open("https://httpbingo.org/cookies")
print(echo.json())
# {'cookies': {'session_id': 'abc123'}}

Para um login real, envie primeiro o formulário de login, depois continue usando o mesmo objeto browser — o cookie de autenticação acompanha todas as páginas subsequentes.

Enviar um formulário de busca e extrair os resultados

Um formulário de busca GET segue o mesmo padrão: defina o campo da consulta, envie, analise as linhas de resultado de browser.page.

python Copy
import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser(
    user_agent="Mozilla/5.0 (compatible; data-collector)"
)
browser.open("https://www.scrapethissite.com/pages/forms/")

browser.select_form('form[action="/pages/forms/"]')
browser["q"] = "boston"
browser.submit_selected()
print(browser.url)  # https://www.scrapethissite.com/pages/forms/?q=boston

rows = browser.page.select("table.table tr.team")
print(f"{len(rows)} linhas")
for row in rows[:3]:
    name = row.select_one(".name").get_text(strip=True)
    year = row.select_one(".year").get_text(strip=True)
    wins = row.select_one(".wins").get_text(strip=True)
    print(name, year, "vitórias:", wins)

Como a página de resultados é renderizada pelo servidor, as linhas estão no HTML que o MechanicalSoup já possui — nenhuma nova busca é necessária.
Obtenha sua chave API no plano gratuito: app.scrapeless.com


MechanicalSoup entrega ao BeautifulSoup tudo o que o servidor retornou via HTTP — nada mais. Quando uma página constrói seu conteúdo com JavaScript do lado do cliente, esse HTML bruto é uma casca vazia, e os seletores não encontram nada:

python Copy
import mechanicalsoup

browser = mechanicalsoup.StatefulBrowser()
browser.open("https://quotes.toscrape.com/js/")
quotes = browser.page.select(".quote .text")
print("Cotações encontradas pelo MechanicalSoup:", len(quotes))
# Cotações encontradas pelo MechanicalSoup: 0

Zero. A variante /js/ dessa página injeta suas citações com JavaScript após o carregamento, então não há nada no HTML do servidor para o BeautifulSoup combinar. A mesma barreira aparece em páginas que estão sob um desafio anti-bot ou que servem conteúdo apenas para um IP residencial — nada disso um cliente apenas HTTP pode superar.

A solução mantém tudo que você já escreveu. Deixe o Scrapeless Scraping Browser fazer a renderização: o SDK cria uma sessão em nuvem, o Playwright se conecta a ela via CDP e executa o JavaScript da página, e você passa o HTML renderizado diretamente para os mesmos seletores do BeautifulSoup.

Instale o SDK e um cliente Playwright, depois busque o executável do navegador que o Playwright controla:

bash Copy
pip install scrapeless playwright beautifulsoup4
python -m playwright install chromium

Defina sua chave no ambiente — nunca a codifique diretamente:

bash Copy
export SCRAPELESS_API_KEY="seu_token_api_aqui"

Agora renderize a página do lado da nuvem e analise o resultado localmente:

python Copy
import os
from scrapeless import Scrapeless
from scrapeless.types import ICreateBrowser
from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup

client = Scrapeless()  # lê SCRAPELESS_API_KEY do ambiente

# Crie uma sessão em nuvem; fixe a saída residencial dos EUA para páginas com restrições geográficas
session = client.browser.create(ICreateBrowser(
    session_name="mechanicalsoup-guide",
    session_ttl=180,
    proxy_country="US",
))

with sync_playwright() as p:
    # browser_ws_endpoint é uma URL padrão wss:// CDP
    browser = p.chromium.connect_over_cdp(session.browser_ws_endpoint)
    page = browser.contexts[0].pages[0]
    page.goto("https://quotes.toscrape.com/js/", wait_until="domcontentloaded")
    page.wait_for_selector(".quote .text")
    html = page.content()
    browser.close()

# Mesma análise do BeautifulSoup que você usou com o MechanicalSoup
soup = BeautifulSoup(html, "html.parser")
quotes = soup.select(".quote .text")
print("Cotações encontradas pelo Scrapeless + BeautifulSoup:", len(quotes))
print(quotes[0].get_text())
# Cotações encontradas pelo Scrapeless + BeautifulSoup: 10
# “O mundo como o criamos é um processo do nosso pensamento. …”

A página que retornou 0 linhas para o MechanicalSoup retorna 10 através do navegador em nuvem, porque o JavaScript realmente foi executado antes que o HTML fosse lido. A renderização e a saída ocorrem do lado da nuvem; a camada de análise — soup.select(...) — é idêntica. Para uma abordagem nativa da biblioteca sobre a mesma escalada, o guia de navegador em nuvem Scrapling roteia um buscador de seletor adaptativo através do mesmo browser_ws_endpoint.


Solução de Problemas

Sintoma Causa Solução
LinkNotFoundError em select_form O seletor CSS não corresponde a nenhum formulário na página Imprima browser.page.select("form") e dirija-se ao action/atributos reais
Seletor de resultados retorna uma lista vazia A página renderiza seu conteúdo com JavaScript Renderize do lado da nuvem com o Scraping Browser, depois analise o HTML retornado
A submissão ignora um campo O campo é um rádio/caixa de seleção que precisa de uma string ou lista, e não um valor simples Atribua uma única string aos rádios, uma lista aos grupos de caixas de seleção
Uma página logada age como se estivesse desconectada Um novo StatefulBrowser (nova jar de cookies) por passo Reutilize um objeto browser para que o cookie da sessão persista
A página retorna um desafio em vez de conteúdo Desafio anti-bot ativo ou uma verificação de região em um cliente apenas HTTP Defina proxy_country e deixe a impressão digital do navegador em nuvem renderizar a página real

Conclusão: mantenha o parser, troque o fetch

MechanicalSoup é a ferramenta certa para o grande conjunto de sites que ainda são HTML simples e formulários: abra uma página, select_form, atribua campos, submit_selected(), e leia as linhas do BeautifulSoup. O jarro de cookies permite que logins e fluxos de múltiplas etapas funcionem sem código extra. Sua única limitação é JavaScript — ele lê HTML, não o renderiza. Quando um alvo se constrói no navegador ou se esconde atrás de um muro anti-bot, a solução mais limpa é mudar apenas a busca: crie uma sessão Scrapeless, renderize a página através do CDP e alimente o HTML resultante nos mesmos seletores. Quando a página precisa de um navegador headless completo com sua própria saída de proxy, o guia de proxy do Puppeteer cobre o mesmo padrão do lado da nuvem, e a doc do Scraping Browser documenta toda a superfície do CDP. Fixe a saída dos EUA para páginas geo-limitadas, reutilize uma sessão entre etapas e trate campos ausentes como nulos.


Pronto para Construir Seu Pipeline de Dados Potencializado por IA?

Junte-se à nossa comunidade para reivindicar um plano gratuito e conectar-se com desenvolvedores que estão construindo automações de formulários e pipelines de rendering: Discord · Telegram.

Inscreva-se em app.scrapeless.com para obter o tempo de execução gratuito do Scraping Browser e adapte os padrões acima aos formulários, logins e páginas renderizadas que seu fluxo de trabalho precisa. Veja preços para escalabilidade.


FAQ

P: O MechanicalSoup executa JavaScript?
Não. O MechanicalSoup envolve requests e BeautifulSoup, portanto, ele só vê o HTML que o servidor retorna. Páginas que constroem seu conteúdo no lado do cliente retornam vazias; renderize essas através de um navegador na nuvem e analise o HTML resultante com os mesmos seletores do BeautifulSoup.

P: Como o MechanicalSoup lida com logins e sessões?
Um único StatefulBrowser reutiliza uma requests.Session, então qualquer cookie que o servidor definir persiste em cada solicitação posterior automaticamente. Envie o formulário de login uma vez, então continue usando o mesmo objeto de navegador e o cookie de autenticação segue junto.

P: Como seleciono um formulário específico em uma página?
Passe um seletor CSS para select_form, por exemplo browser.select_form('form[action="/post"]'). Se nenhum formulário corresponder, você receberá um LinkNotFoundError — imprima browser.page.select("form") para ver os atributos reais e direcionar um deles.

P: É legal fazer scraping em um site com MechanicalSoup?
Fazer scraping de dados visíveis publicamente é geralmente permitido, mas as regras variam de acordo com a jurisdição e os termos de serviço do site. Revise os ToS do alvo, respeite as diretrizes dos robôs, evite dados pessoais ou restritos e consulte um advogado para qualquer coisa ambígua.

P: Preciso de um proxy com MechanicalSoup?
Para páginas abertas renderizadas pelo servidor, muitas vezes não. Para páginas que restrigem por região ou que servem conteúdo apenas para IPs residenciais, direcione a busca através do Scraping Browser do Scrapeless e fixe proxy_country para que a solicitação saia de um IP que o site confia.

P: Posso manter meu código BeautifulSoup quando me mover para o navegador na nuvem?
Sim. O navegador na nuvem substitui apenas a etapa de busca — ele devolve HTML renderizado, que você analisa com as mesmas chamadas soup.select(...) que usou com o MechanicalSoup. A camada de parsing não muda.

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