Mistral Web Scraping: Lendo Dados Ocultos em Atributos HTML
Scraping and Proxy Management Expert
TL;DR:
- Mistral lê dados que não estão no texto visível, e uma execução ao vivo prova isso. Alimentado com uma página de catálogo de laptops renderizada,
mistralai/ministral-3b-2512retornou 6 produtos com o nome completo e não truncado do produto e uma classificação numérica — ambos os valores que vivem apenas em atributos HTML, não no texto que um leitor vê. - O nível mais barato atual do Mistral é uma linha dedicada de modelos pequenos, não uma versão reduzida do carro-chefe. Ministral 3 é a família eficiente construída sob medida da Mistral; este guia verificou o catálogo OpenRouter ao vivo para a entrada mais barata atual, em vez de reutilizar um nome mais antigo "Mistral 7B" da memória.
- O modelo ainda não consegue buscar. Renderização, sessões e desafios de acesso pertencem a uma camada de busca; este guia realiza uma POST por página através da Scrapeless Universal Scraping API.
- Dados apenas de atributos são uma verdadeira armadilha de extração. O texto visível do link de uma página pode ler
"Packard 255 G2..."enquanto o verdadeiro nome do produto está inteiro em um atributotitlea poucos caracteres de distância — o esquema e o nome do prompt deste guia indicam exatamente onde ler. - Sem chave Mistral ainda? A solicitação idêntica passa pelo OpenRouter. Este guia a executou ao vivo no
mistralai/ministral-3b-2512e mostra a saída capturada. - Grátis para começar na parte de busca. Crie sua chave da API Scrapeless em app.scrapeless.com.
O Mistral pode raspar sites?
Mistral extrai; não coleta. Envie-o texto da página e um esquema e ele retorna os campos que você nomear — de forma econômica, já que os preços da linha de modelos pequenos estão entre os mais baixos de qualquer API atual. O que ele não consegue fazer é recuperar uma URL, executar o JavaScript que monta uma página ou gerenciar sessões e desafios de acesso em volume de raspagem. Esse trabalho pertence a uma camada de busca, mantida separada do modelo de propósito.
Esta é uma superfície genuinamente aberta: nenhum post anterior neste site aborda como combinar o Mistral com uma camada de busca ao vivo para extração da web. Para a pergunta adjacente de qual família de modelos atingir, o explicador de raspadores LLM e a lista classificada de raspadores LLM cobrem a categoria.
Instalar
O SDK oficial do Mistral cobre o caminho nativo, openai cobre o caminho OpenRouter e requests cobre a camada de busca:
bash
pip install "mistralai==2.7.2" "openai==2.48.0" requests
Configurar
bash
export MISTRAL_API_KEY="sua_chave_mistral"
export SCRAPELESS_API_KEY="sk_sua_chave_scrapeless"
Buscar uma página onde os dados reais estão ocultos em atributos
O alvo da demonstração é um sandbox público de catálogo de laptops onde o link do produto visível é truncado ("Packard 255 G2...") mas o nome completo está naquele mesmo link em um atributo title, e a classificação em estrelas não é obtida a partir de marcação de ícones, mas de um valor data-rating em um elemento envolvente. Um POST para a Universal Scraping API retorna a página renderizada:
python
# fetch_laptops.py — um POST retorna a página de catálogo de laptops renderizada
import os
import requests
resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={
"Content-Type": "application/json",
"x-api-token": os.environ["SCRAPELESS_API_KEY"],
},
json={
"actor": "unlocker.webunlocker",
"input": {
"url": "https://webscraper.io/test-sites/e-commerce/static/computers/laptops",
"method": "GET",
"js_render": True,
},
},
timeout=120,
)
resp.raise_for_status()
html = resp.json().get("data", "")
print(f"buscou {len(html):,} caracteres")
print("cartões de produtos:", html.count('class="card thumbnail"'))
with open("page.html", "w", encoding="utf-8") as f:
f.write(html)
A execução imprime 6 cartões de produtos de uma página de catálogo ao vivo hospedada em um site público de prática de raspagem — uma página pequena, deliberadamente limitada, em vez da lista completa de centenas de itens que o mesmo domínio também serve.
Implementação básica: Mistral como o extractor
O método chat.complete do SDK oficial aceita response_format={"type": "json_object"}, conforme documentado em referência do modo JSON da Mistral. O nível mais barato atual da Mistral é ministral-3b-2512 — o menor modelo da família Ministral 3, não um nome mais antigo do Mistral 7B que ainda circula em tutoriais antigos.
Nota: Este bloco precisa de uma
MISTRAL_API_KEYcom crédito — o único pré-requisito que este guia não assume. A próxima seção executa a extração idêntica ao vivo através do OpenRouter, com a saída capturada.
python
# extract_mistral.py — extração nativa da Mistral (requer MISTRAL_API_KEY)
import json
import os
from mistralai.client import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
page_html = open("page.html", encoding="utf-8").read()
response = client.chat.complete(
model="ministral-3b-2512",
temperature=0,
max_tokens=2000,
response_format={"type": "json_object"},
messages=[
{
"role": "system",
"content": 'Extraia todos os laptops. Responda SOMENTE com JSON: '
'{"laptops":[{"title":str,"price_usd":number,"rating":int,"review_count":int}]}. '
"title é o nome completo do produto a partir do atributo title do link, não o texto visível truncado. "
"rating é de 1 a 5, leia a partir do atributo data-rating.",
},
{"role": "user", "content": page_html},
],
)
data = json.loads(response.choices[0].message.content)
print(f"extraídos {len(data['laptops'])} laptops")
Sem truque de preenchimento, sem objeto de esquema separado — response_format por si só é suficiente para o modo JSON da Mistral.
Sem chave Mistral? Execute através do OpenRouter
Como ambas as superfícies falam o mesmo contrato de modo JSON, a variante agregadora difere apenas pelo cliente e URL base. Esta é a versão que este guia executou de fato, busca e extração em um único script autossuficiente:
python
# extract_openrouter.py — a mesma extração, executada via OpenRouter
import json
import os
import requests
from openai import OpenAI
resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={
"Content-Type": "application/json",
"x-api-token": os.environ["SCRAPELESS_API_KEY"],
},
json={
"actor": "unlocker.webunlocker",
"input": {
"url": "https://webscraper.io/test-sites/e-commerce/static/computers/laptops",
"method": "GET",
"js_render": True,
},
},
timeout=120,
)
resp.raise_for_status()
page_html = resp.json().get("data", "")
client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_API_KEY"])
completion = client.chat.completions.create(
model="mistralai/ministral-3b-2512",
temperature=0,
max_tokens=2000,
response_format={"type": "json_object"},
messages=[
{
"role": "system",
"content": 'Extraia todos os laptops. Responda SOMENTE com JSON: '
'{"laptops":[{"title":str,"price_usd":number,"rating":int,"review_count":int}]}. '
"title é o nome completo do produto a partir do atributo title do link, não o texto visível truncado. "
"rating é de 1 a 5, leia a partir do atributo data-rating.",
},
{"role": "user", "content": page_html},
],
)
data = json.loads(completion.choices[0].message.content)
print(f"extraídos {len(data['laptops'])} laptops")
for row in data["laptops"]:
print(json.dumps(row, ensure_ascii=False))
A execução ao vivo retornou todos os 6 laptops, cada campo correspondendo exatamente à página fonte:
text
extraídos 6 laptops
{"title": "Packard 255 G2", "price_usd": 416.99, "rating": 2, "review_count": 2}
{"title": "Aspire E1-510", "price_usd": 306.99, "rating": 3, "review_count": 2}
{"title": "ThinkPad T540p", "price_usd": 1178.99, "rating": 1, "review_count": 2}
{"title": "ProBook", "price_usd": 739.99, "rating": 4, "review_count": 8}
{"title": "ThinkPad X240", "price_usd": 1311.99, "rating": 3, "review_count": 12}
{"title": "Aspire E1-572G", "price_usd": 581.99, "rating": 1, "review_count": 2}
Cada título, preço, classificação e contagem de avaliações corresponde exatamente ao código-fonte — o modelo leu o atributo title para o nome completo em vez do texto do link truncado, e o atributo data-rating em vez de contar a marcação de ícones. A chamada total: 28.797 tokens, quase todos de entrada, porque a página buscada carrega uma página completa de navegação e elementos de script ao redor de seis pequenos cartões de produtos.
Obtenha sua chave de API no plano gratuito: app.scrapeless.com
Padrões avançados
- Diga exatamente onde um valor está localizado quando não está no texto visível. "Leia o título completo do atributo
title" e "leia a avaliação dodata-rating" são o que produziram a saída correta aqui — um prompt que diz apenas "extraia o título" convida o modelo a retornar a string truncada que pode ver. - Observe a relação de tokens de entrada para saída. Esta execução gastou 28.554 tokens na entrada contra apenas 243 na saída — o chrome ao redor da página, não os seis registros, domina a conta. Cortar para o contêiner do grid de produtos antes de enviar reduziria isso significativamente, sem perda de conteúdo extraível.
- Mantenha a temperatura em zero para extração. Modelos ministral respondem bem a
temperature=0para tarefas estruturadas; qualquer valor mais alto reintroduz o risco de paráfrase que derrota campos de correspondência exata como um atributo de título. - Reserve os maiores níveis do Mistral para páginas verdadeiramente difíceis. O nível 3B leu dados codificados em atributos sem erros aqui; aumente apenas se um campo específico continuar retornando incorreto em uma entrada de outra forma limpa.
Solucionando problemas
- Títulos voltam truncados, correspondendo apenas ao texto visível. O prompt não disse para ler o atributo. Nomeie a origem exata ("o atributo
titledo link") em vez do campo sozinho. - Avaliações estão erradas ou todas idênticas. O valor geralmente reside em um atributo (
data-rating) em vez de um ícone contável ou um número simples no texto — diga onde ele reside, assim como o prompt deste guia faz. - Menos laptops do que a página realmente tem. Verifique primeiro a contagem de cartões do HTML buscado, da maneira que o script de busca acima faz — uma busca curta é um problema de renderização, não algo que o prompt de extração pode corrigir.
- A saída varia entre execuções idênticas. Defina
temperature=0; extração é uma tarefa de transcrição, não uma tarefa gerativa.
Conclusão
O nível mais barato atual do Mistral lidou com uma armadilha real de forma limpa: um título visível truncado, uma avaliação escondida em um atributo de dados, e leu ambos corretamente com nada mais do que uma flag response_format e duas frases dizendo onde os verdadeiros valores estão. O que o modelo ainda não consegue fazer é buscar essa página em primeiro lugar — um POST através de uma camada de busca dedicada fornece o HTML, e o esquema de seis linhas acima o transforma em registros com tipo, sem código seletor em nenhum lugar do pipeline.
Pronto para fornecer páginas reais ao Mistral?
A camada de busca aqui é a API Universal Scraping — planos e volumes de solicitações estão na página de preços, com cada parâmetro unlocker.webunlocker na documentação do desenvolvedor. Crie uma chave no plano gratuito em app.scrapeless.com e ambos os scripts funcionam como escrito.
FAQ
Q: O Mistral pode raspar sites por conta própria?
Não. A API do Mistral extrai de texto que você fornece; não pode emitir solicitações HTTP, renderizar JavaScript ou manter uma sessão. Cada configuração de raspagem funcional do Mistral a emparelha com uma camada de busca que retorna conteúdo de página fiel.
Q: Qual modelo Mistral devo usar para extração de raspagem na web?
ministral-3b-2512 — o nível mais barato atual na família de pequenos modelos Ministral 3 dedicados, verificado contra o catálogo ao vivo da OpenRouter em vez de um nome mais antigo "Mistral 7B". A execução ao vivo neste guia o usou e retornou todos os 6 registros com cada campo correspondendo exatamente à página de origem.
Q: Como o Mistral lida com dados que estão escondidos em atributos HTML em vez de texto visível?
Corretamente, quando o prompt diz onde olhar. A mensagem do sistema deste guia nomeou o atributo exato tanto para o título não truncado quanto para a avaliação numérica; sem essa instrução, um modelo tende a retornar o texto truncado que pode ver visualmente.
Q: Mistral local via Ollama versus a API — qual devo usar para extração de raspagem?
O caminho da API neste guia não precisa de GPU local ou download de modelo e retorna resultados em uma solicitação; uma implantação local do Ollama troca essa conveniência por custo zero por token e total localidade de dados. Ambos apontam a mesma arquitetura de buscar-para-extrair em diferentes ambientes de execução — escolha a API para trabalhos de baixo volume ou esporádicos, local para trabalhos de alto volume ou sensíveis a dados.
Q: É legal raspar com Mistral?
A camada de extração não altera as regras de coleta. Busque apenas páginas públicas, respeite os termos do site e as diretivas de robôs padronizadas pelo Protocolo de Exclusão de Robôs, mantenha os volumes limitados e trate quaisquer dados pessoais conforme a legislação aplicável — além dos termos de uso da Mistral no lado do modelo.
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.



