niquests ウェブスクレイピング: PythonのためのモダンなHTTP/2リクエスト
Senior Web Scraping Engineer
TL;DR:
- niquestsはrequestsのドロップイン置き換えで、同じAPIにHTTP/2、HTTP/3、接続の多重化を追加 — インポートを変更するだけでコードはそのまま動作します。
- niquestsが行わないことはJavaScriptをレンダリングすることです。 これはHTTPクライアントであり、スクリプト生成されたページではサーバーが送信したマークアップを返し、その中にはコンテンツが含まれていません。
- そのギャップは1つのスクリプトで現れます。 niquestsはHTTP/2経由でJavaScriptでレンダリングされたデモページを取得し、その中に引用ブロックが0個あることを確認しました。
- niquestsはScrapelessを呼び出すクライアントでもあります。 ライブ実行では同じセッションを使用してURLをScrapeless Universal Scraping APIにPOSTし、レンダリングされたHTMLを受け取り、その中から全10人の著者を抽出しました。
- 1つのHTTPクライアントで両方の仕事を行います。 コンテンツを直接提供するページを直接取得し、スクリプトで生成されるページにはレンダリングAPIを呼び出す — 同じ
Session、同じAPIです。 - 取得側は無料で始められます。 app.scrapeless.comでScrapeless APIキーを作成してください。
niquestsが何であるか、何でないか
niquestsはrequestsのフォークで、すでに知っているAPI — Session、get、post、json() — を維持し、requestsが持っていなかったトランスポート機能、すなわちHTTP/2、HTTP/3、接続の多重化、DNS-over-HTTPS を追加しました。スクレイパーにとっての実際の利点は、import niquests as requests が既存のコードベースを改写なしで最新のHTTPにアップグレードし、多重化されたトランスポートが少ない接続で多くのリクエストを移動させることです。
それが何でないかは、ブラウザです。niquestsはHTTPを使用しているため、サーバーが送信する内容を正確に返します。モダンなページのコンテンツを構築するJavaScriptを実行しません。より速く、よりモダンなトランスポートに変更しても、それは変わりません — HTTP/2経由で取得した空のページは依然として空です。したがって、niquestsのスクレイパーは1つのクライアントで2つの仕事を行います:コンテンツを直接提供するページを取得し、スクリプトで生成されるページにはレンダリングAPIを呼び出す。このガイドでは、niquests自体がその呼び出しを行うためにScrapeless Universal Scraping APIを使用します。より広範なツールキットについては、Pythonのウェブスクレイピングチュートリアルが付属しています。
インストール
niquestsはツールチェーン全体であり、このガイドのために別のパーサーを必要としません。このガイドが書かれたバージョンはniquests 3.20.1です:
bash
pip install "niquests==3.20.1"
キーは環境に保持し、決してソース内には入れないでください:
bash
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"
直接取得とその停止する場所
niquestsをJavaScriptでレンダリングされたページに向けると、2つのことが同時に真となります:トランスポートは現代的であり、コンテンツは欠落しています。接続はHTTP/2を交渉します — requestsが話さないプロトコルです — しかし、戻されたマークアップにはゼロ引用ブロックが含まれています。なぜなら、コンテンツはクライアントサイドで構築されるからです:
python
# direct.py — 現代的なトランスポート、欠落したコンテンツ
import niquests
session = niquests.Session()
resp = session.get("https://quotes.toscrape.com/js/", timeout=30)
print("http version:", resp.conn_info.http_version)
print("js-page quote blocks:", resp.text.count('class="quote"'))
トランスポートはHTTP/2ですが、内容はそこにありません:
text
http version: HttpVersion.h2
js-page quote blocks: 0
そのゼロはniquestsの失敗ではありません — これは、スクリプトが実行された後にコンテンツが到着するページに対するHTTPクライアントの正しい結果です。解決策は、レンダリングを行う取得レイヤーです。
レンダリングされた取得、niquestsがScrapelessを呼び出す
同じセッションを保持し、対象を変更します:ページの代わりに、そのURLをScrapeless Universal Scraping APIにPOSTします。これはサーバーサイドでレンダリングし、完成したHTMLを返します。niquestsはこのリクエストを他のリクエストと同様に処理しますので、1つのクライアントが両方のパスをカバーします — ここでのリクエストとレスポンスレイヤーは、HTTPセマンティクス標準に従います:
python
# rendered.py — niquestsがレンダリングAPIを呼び出し、その後抽出します
import os
import re
import niquests
session = niquests.Session()
resp = session.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
timeout=120,
)
resp.raise_for_status()
html = resp.json()["data"]
authors = re.findall(r'<small class="author">(.*?)</small>', html)
print("rendered quote blocks:", html.count('class="quote"'))
print("authors extracted:", len(authors))
print("first author:", authors[0])
これでコンテンツが存在し、抽出可能になりました:
text
rendered quote blocks: 10
authors extracted: 10
最初の著者: アルバート・アインシュタイン
それが全体のスクレーパーで、niquestsを離れることはありませんでした: 1つの`Session`が機能する場合に直接リクエストを行い、レンダリングが必要な場合にはScrapelessリクエストを行います。[Universal Scraping API](https://www.scrapeless.com/ja/product/universal-scraping-api?utm_source=website&utm_medium=blog&utm_campaign=universalscrapingapi&utm_term=niquests-web-scraping)がレンダリングを行い、niquestsがHTTPを処理します。
> 無料プランでAPIキーを取得: [app.scrapeless.com](https://app.scrapeless.com/passport/login?utm_source=website&utm_medium=blog&utm_campaign=universalscrapingapi&utm_term=niquests-web-scraping)
## 高度なパターン
- **1行で移行。** `import niquests as requests`を使用すると、既存の`requests`コードベースが他の変更なしにHTTP/2とマルチプレクシングを採用できます; APIは同じです。
- **セッションを再利用。** 単一の`niquests.Session()`が接続をプールしてマルチプレクシングするため、多くのリクエストを行う際にトランスポートの利点が現れます — 一度構築してそれを回します。
- **正規表現を超えた場合は実際のパーサーを追加。** ここでは正規表現を使用して例を1つの依存関係に制限しています; フラットなリスト以上の場合は、`resp.json()["data"]`をセレクタライブラリに渡し、構造化されたフィールドを選択します。
- **交渉させる。** niquestsはサーバーがHTTP/2またはHTTP/3を提供すると選択し、それがない場合はクリーンにフォールバックします; バージョンを設定する必要はなく、確認したいときに`conn_info`から読み取ります。
## トラブルシューティング
- **`conn_info.http_version`がHTTP/1.1。** サーバーがそのリクエストに対してHTTP/2を提供していなかったか、仲介者がダウングレードしました。これは通常のことで、エラーではありません; niquestsは利用可能な最良のバージョンを使用します。
- **ブラウザで表示できるページからゼロブロック。** コンテンツがJavaScriptでレンダリングされていて、直接取得した結果が事前レンダリングされたHTMLを返しました — `js-page quote blocks: 0`のケース。このURLを代わりに`js_render`を使ってScrapeless呼び出しを通してルーティングしてください。
- **Scrapelessレスポンスで`json()`がエラー。** リクエストはレンダリング前に失敗しました。最初に`raise_for_status()`を呼び出し、キーが設定されていて、アクターと入力が示されている通りに整形されていることを確認します。
- **遅いページでのタイムアウト。** レンダリングには静的な取得よりも時間がかかります。例のようにScrapeless POSTに十分な`timeout`を与えてください; 直接リクエストに使用する短いデフォルトではありません。
## 結論
niquestsはスクレイパーが必要とする1つのHTTPクライアントとしての地位を確保しています: `requests` APIと現代のトランスポートを備え、直接の取得とレンダリングAPIへの呼び出しの両方を処理します。スクリプトで構築されたページをコンテンツに変える層は取得です — 直接リクエストのゼロブロック結果がそれを解決します — そして、niquests自体が行う1つのScrapeless POSTがギャップを埋めます。2つのパスを単一のセッションに配線し、デモページの10人の著者がリライトなしでHTTP経由で戻ってきます。
[無料のScrapelessアカウントを作成](https://app.scrapeless.com/passport/login?utm_source=website&utm_medium=blog&utm_campaign=universalscrapingapi&utm_term=niquests-web-scraping)してAPIキーを取得してください。また、[開発者ドキュメント](https://docs.scrapeless.com?utm_source=website&utm_medium=blog&utm_campaign=universalscrapingapi&utm_term=niquests-web-scraping)では`unlocker.webunlocker`パラメータについて説明しています。定期ジョブを計画している場合は、[Scrapelessの価格](https://www.scrapeless.com/ja/pricing?utm_source=website&utm_medium=blog&utm_campaign=universalscrapingapi&utm_term=niquests-web-scraping)を確認してください。
## FAQ
**Q: niquestsはJavaScriptでレンダリングされたページを自力でスクレイピングできますか?**
いいえ。niquestsはHTTPクライアントであり、ブラウザではありません; サーバーが送信したマークアップを返し、スクリプトは実行しません。クライアント側でコンテンツを構築するページでは、直接取得した結果にコンテンツが欠けています — ガイドのゼロブロック結果です。そのようなページはScrapeless Universal Scraping APIを通してルーティングし、レンダリングを行い、niquestsもその呼び出しを行います。
**Q: niquestsはrequestsとどのように異なりますか?**
同じAPIで、新しいトランスポート。niquestsは、`Session`、`get`、`post`、および`json()`を同一に保ちながら、HTTP/2、HTTP/3、接続のマルチプレクシング、およびDNS-over-HTTPSを追加する`requests`のフォークです。`import niquests as requests`が通常の完全な移行です。
**Q: 別のパーサーが必要ですか?**
フィールドのフラットなリストの場合、正規表現または標準ライブラリで十分です。ネストされたまたは構造化された抽出が必要な場合は、niquestsとセレクタライブラリを組み合わせてください — niquestsが取得し、パーサーが選択します。このガイドは故意に1つの依存関係に留まっています。
**Q: HTTP/2はスクレイピングブロックに役立ちますか?**
それはトランスポートのアップグレードであり、ブロッキング対策ではありません。HTTP/2のマルチプレクシングは、多くのリクエストを通じてスループットを改善しますが、JavaScriptをレンダリングしたり、アクセスの課題をクリアしたりするわけではありません — それは取得層の仕事です。そのため、レンダリングされたパスはScrapelessを通ります。
**Q: niquestsでのスクレイピングは合法ですか?**
HTTPクライアントはコレクションルールを変更しません。公開ページのみを取得し、サイトの利用規約と<a href="https://datatracker.ietf.org/doc/html/rfc9309" rel="nofollow"><strong>ロボット除外プロトコル</strong></a>によって標準化されたロボット指令を尊重し、ボリュームを制限し、適用される法律に従って個人データを処理してください。
Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。



