🎯 カスタマイズ可能で検出回避型のクラウドブラウザ。自社開発のChromiumを搭載し、ウェブクローラーAIエージェント向けに設計されています。👉今すぐ試す
ブログに戻ります

インターネットウェブスクレイピング:ブラウザTLSフィンガープリンティングのなりすまし

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

23-Jul-2026

TL;DR:

  • rnetは本物のブラウザのTLSフィンガープリントを模倣する非同期HTTPクライアントです。これにより、ハンドシェイクをプロファイルするサーバーはPythonのデフォルトではなく、Chromeを見ることになります。Rustで構築され、Pythonに公開されています。
  • rnetが行わないことはJavaScriptをレンダリングすることです。 完璧なフィンガープリントがリクエストを受理させますが、ページのコンテンツを構築するスクリプトを実行することはありません。
  • このガイドのフィンガープリントは実際のものです。 Chromeを模倣したライブ実行では、HTTP/2上でブラウザ型のJA3とt13d1516h2 JA4が生成されましたが、スクリプトによって構築されたページでは0の引用ブロックが見つかりました。
  • rnetはScrapelessを呼び出すクライアントでもあります。 同じ非同期クライアントがURLをScrapeless Universal Scraping APIにPOSTし、レンダリングされたHTMLを取得し、10人の著者全員を引き出しました。
  • 二つの異なる問題、きれいに分離されています。 rnetはTLSフィンガープリント層を処理し、Scrapelessはレンダリングを処理します。お互いの代わりにはなりません。
  • フェッチ側の開始は無料です。 app.scrapeless.comでScrapeless APIキーを作成してください。

rnetとは何か、そして何ではないのか

rnetはRustのネットワークスタックに基づいて構築されたPython用の非同期HTTPクライアントで、その特筆すべき特徴はTLSとHTTPフィンガープリントの模倣です。クライアントがTLS接続を開くと、そのハンドシェイクの正確な形状—暗号の順序、拡張、曲線—がサーバーがプロファイルできるフィンガープリントを形成します。標準的なPythonクライアントは、ブラウザが生成しないフィンガープリントを持っており、いくつかのサイトではHTMLの1バイトも提供される前にそれを拒否します。rnetは選択したブラウザのハンドシェイクを再現するため、接続はChromeやFirefoxとして読み取られ、非同期APIを介してHTTP/2で実行されます。

rnetが何でないかは、レンダラーではありません。合致するフィンガープリントはハンドシェイクレベルのプロファイリングを通過させますが、JavaScriptについては何も行いません。ページはスクリプトでコンテンツを構築し続け、rnetは他のHTTPクライアントと同様に、サーバーが送信したマークアップを返します—これはスクリプトによって構築されたページではコンテンツが空です。したがって、rnetスクレイパーは、しばしば混同される二つの問題を分けます:フィンガープリント層、ここでrnetがその位置を得る、そしてレンダリング層、これはブラウザが必要です。このガイドでは、レンダリングのためにScrapeless Universal Scraping APIを使用し、rnetが呼び出しを行います。全体像については、Pythonウェブスクレイピングチュートリアルが関連資料です。

インストール

rnetはこのガイドのための全ツールチェーンです。これに対して書かれたバージョンはrnet 2.4.2です:

bash Copy
pip install "rnet==2.4.2"

キーは環境に保存し、ソースには決して保存しないでください:

bash Copy
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

ブラウザを模倣し、どこで止まるかを見る

rnetをブラウザ模倣設定のフィンガープリンティングエンドポイントに向けると、ハンドシェイクはそのブラウザとして読み取られます。JA3とJA4はTLSハンドシェイクの標準的な要約です—TLS 1.3標準の下で交渉されたフィンガープリント—そしてrnetはブラウザ形状の値を生成します。 しかし、スクリプトで構築されたページ上の同じクライアントは何も見つけません。なぜなら、フィンガープリントはクライアント側レンダリングに関しては関係がないからです:

python Copy
# fingerprint.py — 実際のブラウザハンドシェイクとその限界
import asyncio
import json
import re

import rnet

FINGERPRINT_URL = "https://tls.peet.ws/api/all"
PAGE_URL = "https://quotes.toscrape.com/js/"


async def main() -> None:
    client = rnet.Client(impersonate=rnet.Impersonate.Chrome131)

    resp = await client.get(FINGERPRINT_URL)
    fp = json.loads(await resp.text())
    ja3 = fp.get("tls", {}).get("ja3_hash", "")
    ja4 = fp.get("tls", {}).get("ja4", "")
    print("ja3は32桁の16進数:", bool(re.fullmatch(r"[0-9a-f]{32}", ja3)))
    print("ja4の接頭辞:", ja4.split("_")[0])
    print("HTTPバージョン:", fp.get("http_version"))

    page_resp = await client.get(PAGE_URL)
    page = await page_resp.text()
    print("jsページの引用ブロック:", page.count('class="quote"'))


asyncio.run(main())

ハンドシェイクはブラウザ形状ですが、ページはまだ空です:

text Copy
ja3は32桁の16進数: True
ja4の接頭辞: t13d1516h2
HTTPバージョン: h2
jsページの引用ブロック: 0

JA3ハッシュは意図的に実行ごとに変動します—ブラウザはGREASEメカニズムの下で一つの拡張をランダム化し、rnetはそれを再現します—したがって、スクレイパーは形状を確認します。固定された値ではありません。 JA4の接頭辞t13d1516h2は安定した部分です:TLS 1.3、16の暗号スイート、16の拡張、HTTP/2。それが行わないことはページをレンダリングすることです。

rnetによって呼び出されたScrapelessでレンダリングする

同じ非同期クライアントを維持し、ターゲットを変更します:URLをScrapeless Universal Scraping APIにPOSTし、サーバーサイドでレンダリングし、完了したHTMLを返します。rnetはこのリクエストを他のリクエストと同様に処理するため、一つのクライアントがフィンガープリン敏感なフェッチとレンダリングされたものの両方をカバーします:

python Copy
# rendered.py — rnetがレンダーAPIを呼び出し、その後抽出する
import asyncio
import json
import os
import re

import rnet


async def main() -> None:
    client = rnet.Client(impersonate=rnet.Impersonate.Chrome131)
    resp = await client.post(
        "https://api.scrapeless.com/api/v2/unlocker/request",
        headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"], "Content-Type": "application/json"},
        json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
    )
    html = json.loads(await resp.text())["data"]

    authors = re.findall(r'<small class="author">(.*?)</small>', html)
    print("レンダリングされた引用ブロック:", html.count('class="quote"'))
    print("最初の著者:", authors[0])


asyncio.run(main())

これでコンテンツが表示されます:

text Copy
レンダリングされた引用ブロック: 10
最初の著者: アルバート・アインシュタイン

これが全体のスクレイパーであり、rnetの中で完結しています:ブラウザのフィンガープリントを持つ非同期クライアントがレンダー呼び出しも行います。Universal Scraping APIがレンダリングを行い、rnetがHTTPを担当します。

無料プランでAPIキーを取得: app.scrapeless.com

高度なパターン

  • 現在のブラウザに偽装を合わせる。 rnet.Impersonateは特定のブラウザバージョンを公開しています。最近のものを選びましょう。古いビルドのフィンガープリンはシグナルになります。クライアントのAPIはターゲットにかかわらず変わりません。
  • 一つのクライアントを再利用する。 rnet.Clientは接続をプールします;一度作成し、非同期タスクグループ全体で共有することで、リクエストごとに作成するより効率的です。
  • 値ではなく形をチェックする。 GREASEは接続ごとにJA3をランダマイズするため、パターンとJA4プレフィックスを確認します。最初のスクリプトのように、ハードコーディングされたハッシュは使用しません。
  • 形が大きくなったらパーサーを追加する。 regexは一つの依存関係に抑えていますが、ネストされたレコードの場合は、レンダリングされたHTMLをセレクタライブラリに供給し、そこからフィールドを選択します。

デバッグ

  • サイトがリクエストをブロックする。 TLSフィンガープリンは数あるシグナルの一つです。ブラウザ型のハンドシェイクが十分でない場合、ブロックはトランスポートより上にあり、IP評判、ヘッダ、またはチャレンジが原因です — リクエストはScrapeless経路に属し、そこで処理されます。
  • ブラウザで表示できるページからのゼロブロック。 コンテンツはJavaScriptレンダリングされています;フィンガープリンはリクエストを受け付けましたが、スクリプトは実行されませんでした。そのURLをScrapeless呼び出しを通して、js_renderを指定してルーティングします。
  • JA3ハッシュが毎回変更される。 正しいです — GREASEがそれをランダマイズします。実際のブラウザと同様に。パターンとJA4プレフィックスを確認してください。
  • レスポンスでawaitエラー。 rnetは非同期です:リクエストと.text()の読み込みの両方でawaitされ、すべてがasyncio.run内で実行されます。

結論

rnetはハンドシェイクを正しく見せる層としての地位を確立します:非同期でRustバックのクライアントが実際のブラウザのTLSフィンガープリンとレンダー呼び出しを持ちます。解決できない問題はページ自体です — フィンガープリンスクリプトのゼロブロック結果がそれを決定づけます — rnetから送信された一つのScrapeless POSTがそのギャップを埋めます。フィンガープリン層とレンダリング層を一つのクライアントに組み合わせれば、デモページの十人の著者がChromeと認識される接続から戻ってきます。

無料のScrapelessアカウントを作成してAPIキーを取得し、開発者ドキュメントunlocker.webunlockerパラメータを解説します。定期的にジョブを計画する際は、Scrapelessの料金を確認してください。

よくある質問

Q: rnetはJavaScriptレンダリングされたページを自力でスクレイピングできますか?

いいえ。rnetはフィンガープリン偽装のHTTPクライアントです;TLSレイヤーでリクエストを受け付けますが、JavaScriptは実行しません。スクリプトで生成されたページでは、フェッチはコンテンツが不足したマークアップを返します — ガイドのゼロブロック結果のように。それらのページはScrapeless Universal Scraping APIを通してルーティングし、rnetが呼び出しを行います。

Q: TLSフィンガープリン偽装は実際に何をしますか?
rnetのTLSハンドシェイクは選択したブラウザに合わせて調整されるため、JA3またはJA4フィンガープリントをプロファイリングしているサーバーは、一般的なPythonクライアントではなくChromeやFirefoxと認識します。これにより、ハンドシェイクレベルのフィルタリングがクリアされますが、IPベースのブロック、チャレンジページ、JavaScriptのレンダリングの必要性はクリアされません。

Q: rnetはcurl_cffiとどのように異なりますか?

両者ともにブラウザフィンガープリントを模倣します。rnetはRustに基づいており、非同期ファーストです;curl_cffiはcurl-impersonateをラップしており、同期的です。スクレイパーが非同期かどうか、そしてどの模倣ターゲットが必要かで選んでください — レンダリングAPIとの二層パターンはどちらも同じです。

Q: なぜJA3ハッシュは毎回変更されるのですか?

本物のブラウザはGREASEメカニズムを通じて1つのTLS拡張をランダム化するため、rnetはその挙動を再現します。固定されたJA3は人工的に見えてしまいます。特定の値の代わりに、32桁の16進数パターンとJA4プレフィックスを確認してください。

Q: rnetを用いたスクレイピングは合法ですか?

HTTPクライアントは収集ルールを変更しません。公共のページのみを取得し、サイトの利用規約やロボット排除プロトコルによって標準化されたロボット指示に従い、ボリュームを制限し、適用される法律に従って個人データを取り扱ってください。

Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。

最も人気のある記事

カタログ