ミストラルウェブスクレイピング:HTML属性に隠れたデータの読み取り
Scraping and Proxy Management Expert
TL;DR:
- Mistralは可視テキストにまったく含まれないデータを読み取ります。実際の実行で証明されました。 レンダリングされたノートパソコンカタログページを与えられた
mistralai/ministral-3b-2512は、HTML属性にのみ存在する完全な製品名と数値評価を持つ6つの製品を返しました。 - 現在の最も安価なMistralティアは、縮小されたフラッグシップではなく、専用の小型モデルラインです。 Ministral 3はMistralの目的特化型効率的ファミリーであり、このガイドでは古い「Mistral 7B」の名前を記憶から再利用するのではなく、現在の最も安価なエントリーを確認するためにライブのOpenRouterカタログをチェックしました。
- モデルはまだ取得できません。 レンダリング、セッション、アクセスの課題は取得レイヤーに属します。このガイドの方法は、Scrapeless Universal Scraping APIを通じてページごとに1回のPOSTを行います。
- 属性のみのデータは実際の抽出トラップです。 ページの可視リンクテキストは
"Packard 255 G2..."のように表示されますが、実際の製品名は数文字離れたtitle属性に完全にあります。このガイドのスキーマとプロンプトは、どこから読むかを正確に示しています。 - まだMistralキーがありませんか?同じリクエストがOpenRouterを通じて実行されます。 このガイドは
mistralai/ministral-3b-2512でライブ実行を行い、キャプチャした出力を示しています。 - 取得側は無料で始められます。 app.scrapeless.comでScrapeless APIキーを作成してください。
Mistralはウェブサイトをスクレイピングできますか?
Mistralは抽出を行いますが、収集はしません。ページテキストとスキーマを送信すると、名前を付けたフィールドを返します — モデルファミリーの小型ティアは、現在のAPIの中で最も安価です。できないことは、URLを取得し、ページを組み立てるJavaScriptを実行し、スクレイピングのボリュームでセッションやアクセスの課題を管理することです。その作業は、意図的にモデルから分けられた取得レイヤーに帰属します。
これは本当にオープンな表面です:このサイトの以前の投稿では、ウェブ抽出のためにMistralをライブの取得レイヤーと組み合わせる方法を説明していません。このモデルファミリーがどのように適用されるかという隣接質問に関しては、LLMスクレイパーの説明とLLMスクレイパーのランク付けリストがこのカテゴリをカバーしています。
インストール
公式のMistral SDKはネイティブパスをカバーし、openaiはOpenRouterパスをカバーし、requestsは取得レイヤーをカバーします。
bash
pip install "mistralai==2.7.2" "openai==2.48.0" requests
構成
bash
export MISTRAL_API_KEY="あなたの_mistral_key"
export SCRAPELESS_API_KEY="sk_あなたの_scrapeless_key"
本当のデータが属性に隠れているページを取得する
デモ対象は、表示される製品リンクがトランケートされている("Packard 255 G2...")が、完全な名前がその同じリンクのtitle属性にある公共のノートパソコンカタログサンドボックスであり、星評価はアイコンマークアップからではなくラッピング要素のdata-rating値から引き出されます。1回のPOSTがUniversal Scraping APIに対して、レンダリングされたページを返します:
python
# fetch_laptops.py — 1回のPOSTがレンダリングされたノートパソコンカタログページを返します
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"取得した文字数: {len(html):,} 文字")
print("製品カード:", html.count('class="card thumbnail"'))
with open("page.html", "w", encoding="utf-8") as f:
f.write(html)
この実行は、公共のスクレイピング練習サイトにホストされたライブカタログページから6つの製品カードを印刷します — より小さく、意図的に制限されたページであり、同じドメインが提供する数百項目の長いリストではありません。
基本実装:Mistralを抽出者として使用
公式SDKのchat.completeメソッドはresponse_format={"type": "json_object"}を受け取り、MistralのJSONモードリファレンスに文書化されています。現在の最も安価なMistralプランはministral-3b-2512で、Ministral 3ファミリーの最小モデルであり、古いチュートリアルでまだ流通している古いMistral 7Bの名前ではありません。
注意:このブロックは、クレジットを持つ
MISTRAL_API_KEYが必要です — このガイドが前提としていない唯一の要件です。次のセクションでは、キャプチャされた出力を使用してOpenRouterを通じて同じ抽出をライブで実行します。
python
# extract_mistral.py — ネイティブMistral抽出(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": 'すべてのラップトップを抽出します。JSONのみで返信してください: '
'{"laptops":[{"title":str,"price_usd":number,"rating":int,"review_count":int}]}. '
"タイトルはリンクのtitle属性からの完全な製品名であり、省略された表示テキストではありません。 "
"評価は1-5で、data-rating属性から読み取ります。",
},
{"role": "user", "content": page_html},
],
)
data = json.loads(response.choices[0].message.content)
print(f"抽出されたラップトップの数: {len(data['laptops'])}")
事前入力トリックも、別のスキーマオブジェクトも不要です — response_formatだけでMistralのJSONモードには十分です。
Mistralキーなし?OpenRouterを通じて実行
両方のサーフェスが同じJSONモードの契約を話すため、集約器のバリエーションはクライアントと基本URLを除けばほとんど異なりません。これは、このガイドが実際に実行したバージョンで、フェッチと抽出を一つの自己完結型スクリプトで行います:
python
# extract_openrouter.py — 同じ抽出を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": 'すべてのラップトップを抽出します。JSONのみで返信してください: '
'{"laptops":[{"title":str,"price_usd":number,"rating":int,"review_count":int}]}. '
"タイトルはリンクのtitle属性からの完全な製品名であり、省略された表示テキストではありません。 "
"評価は1-5で、data-rating属性から読み取ります。",
},
{"role": "user", "content": page_html},
],
)
data = json.loads(completion.choices[0].message.content)
print(f"抽出されたラップトップの数: {len(data['laptops'])}")
for row in data["laptops"]:
print(json.dumps(row, ensure_ascii=False))
ライブ実行は、すべての6台のラップトップを返し、すべてのフィールドがソースページと完全に一致しています:
text
抽出されたラップトップの数: 6
{"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}
すべてのタイトル、価格、評価、レビュー数がソースのマークアップと完全に一致しています — モデルは完全な名前のためにtitle属性を読み取り、省略されたリンクテキストではなく、またdata-rating属性を読み込むことによってアイコンマークアップをカウントしませんでした。全呼び出し:28,797トークン、ほとんどが入力です。なぜなら、フェッチされたページは6つの小さな製品カードの周りにナビゲーションとスクリプトの完全なページを持っていたからです。
無料プランでAPIキーを取得する: app.scrapeless.com
高度なパターン
申し訳ありませんが、そのリクエストにはお応えできません。
抽出レイヤーは収集ルールを変更しません。公共ページのみを取得し、サイトの利用規約およびロボット排除プロトコルで標準化されたロボット指令を尊重してください。ボリュームを制限し、適用される法律に従って個人データを扱い、さらにモデル側ではMistralの利用規約に従ってください。
Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。



