PythonでHTTPXを使用したWebスクレイピング

Webスクレイピングのための強力なPythonのHTTPクライアントであるHTTPXを探索します。設定、機能、高度なテクニック、リクエストとの比較を学びます。
5 min read
web scraping with httpx and python blog image

この記事では以下のことが学べます:

  • HTTPと、それが提供する機能は何か?
  • ガイド付きセクションでWebスクレイピングにHTTPXを使用する方法
  • Webスクレイピングのための高度なHTTPX機能
  • 自動リクエストのためのHTTPXとリクエストの比較

さっそく始めましょう!

HTTPX とは何ですか?

HTTPX は、Python 3 用のフル機能の HTTP クライアントで、 再試行可能な http ライブラリの上に構築されています。スレッド数が多い場合でも、信頼性の高い結果が得られるように設計されています。HTTPXは、HTTP/1.1およびHTTP/2プロトコルをサポートする同期 APIと非同期APIの両方を提供します。

⚙️ 機能

  • シンプルでモジュール式のコードベースなので簡単に提供。
  • 複数の要素を調査するための高速かつ完全に構成可能なフラグ。
  • さまざまなHTTPベースのプローブ方法をサポート。
  • デフォルトでHTTPSからHTTPへのスマートな自動フォールバック。
  • ホスト、URL、CIDRを入力として受け入れます。
  • プロキシ、カスタムHTTPヘッダー、カスタムタイムアウト、基本認証などをサポート。

👍 長所

  •  httpx [cli]を使用してコマンドラインから利用可能
  • HTTP/2や非同期APIのサポートといった機能が満載。
  • このプロジェクトは積極的に開発されています…

👎 短所

  • …頻繁なアップデートにより、新しいリリースに重大な変更が導入される場合があります。
  •  ライブラリより人気が 低い。

HTTPXによるスクレイピング:ステップバイステップガイド

HTTPXはHTTPクライアントです。つまり、ページの生のHTMLコンテンツの取得に役立ちます。次にHTMLからデータを解析して抽出するには、 BeautifulSoupのようなHTMLパーサーが必要になります。

実際、HTTPXは単なるHTTPクライアントではなく、 Webスクレイピングに最適なPython HTTPクライアントの1つです

BeautifulSoupでWebスクレイピングにHTTPXを使用する方法を学ぶためには、このチュートリアルに従ってください!

警告: HTTPXはプロセスの初期段階でのみ使用されますが、完全なワークフローを順番に説明します。より高度なHTTPX スクレイピング技術に興味がある場合は、ステップ3の後の次の章に進んでください。

ステップ1:プロジェクトを準備する

マシンにPython 3以降がインストールされていることを確認してください。それ以外の場合は、 公式サイトからダウンロードし インストールの手順に従ってください。

それでは、次のコマンドを使用して、HTTPXスクレイピングプロジェクト用のディレクトリを作成します:

mkdir httpx-scraper

そこに移動して、その中の 仮想環境 を初期化します:

cd httpx-scraper
python -m venv env

任意のiPython IDEでプロジェクトフォルダーを開きます。 Python拡張機能を備えたVisual Studio CodeまたはPyCharmコミュニティエディションで大丈夫です。

次に、プロジェクトフォルダ内にscraper.pyファイルを作成します。現在、 scraper.py は空のPythonスクリプトですが、すぐにスクレイピングロジックが含まれます。

IDEのターミナルで仮想環境をアクティブ化します。LinuxまたはmacOSでは、次を実行します:

./env/bin/activate

同様に、Windowsの場合は次のように実行します:

env/Scripts/activate

すばらしい!これで完全に設定が完了しました。

ステップ2:スクレイピングライブラリをインストールする

アクティブ化された仮想環境で、次のコマンドを使用してHTTPXとBeautifulSoupをインストールします:

pip install httpx beautifulsoup4

これにより、 httpx と beautifulsoup4 の両方がプロジェクトの依存関係に追加されました。

これらを scraper.py スクリプトにインポートします:

import httpx
from bs4 import BeautifulSoup

素晴らしい!スクレイピングのワークフローの次のステップに進む準備ができました。

ステップ3:ターゲットページのHTMLを取得する

この例では、ターゲットページは「Quotes to Scrape」サイトです:

Quotes to Scrapeホームページ

HTTPXを使用して、 get () メソッドでホームページのHTMLを取得します:

# Make an HTTP GET request to the target page
response = httpx.get("http://quotes.toscrape.com")

HTTPXは背後でサーバーにHTTP GETリクエストを送信し、サーバーはページのHTMLで応答します。属性を使用して、 response.text HTMLコンテンツにアクセスできます:

html = response.text
print(html)

これで、ページの生のHTMLコンテンツが出力されます:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Quotes to Scrape</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
    <link rel="stylesheet" href="/static/main.css">
</head>
<body>
    <!-- omitted for brevity... -->
</body>
</html>

素晴らしい!このコンテンツを解析して、必要なデータを抽出します。

ステップ4:HTMLを解析する

HTMLコンテンツをBeautifulSoupコンストラクターにフィードして解析します:

# Parse the HTML content using
BeautifulSoup soup = BeautifulSoup(html, "html.parser")

html.parser は、コンテンツの解析に使用される標準のPython HTMLパーサーです。

 soup 変数は解析されたHTMLを保持し、必要なデータを抽出するメソッドを公開しています。

HTTPXはHTMLを取得するという役目を終えたので、BeautifulSoupによる従来のデータ解析フェーズに移行します。詳細については、BeautifulSoup Webスクレイピングのチュートリアルを参照してください。

ステップ5:そこからデータをスクレイピングする

次のコード行を使用して、ページから引用符データを取得できます:

# Where to store the scraped data
quotes = []

# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")

# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
    text = quote_element.find("span", class_="text").get_text().get_text().replace("“", "").replace("”", "")
    author = quote_element.find("small", class_="author")
    tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]

    # Store the scraped data
    quotes.append({
        "text": text,
        "author": author,
        "tags": tags
    })

このスニペットは、スクレイピングされたデータを保存する quotes という名前のリストを定義します。次に、すべての引用HTML要素を選択し、反復して引用テキスト、著作者、タグを抽出します。抽出された各引用は quotes リスト内にディクショナリとして保存され、さらに使用したりエクスポートしたりできるようにデータが整理されます。

はい!スクレイピングロジックが実装されました。

ステップ6:スクレイピングしたデータをエクスポートする

次のロジックを使用して、スクレイピングされたデータをCSVファイルにエクスポートします:

# Specify the file name for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])

    # Write the header row
    writer.writeheader()

    # Write the scraped quotes data
    writer.writerows(quotes)

このスニペットは、 quotes.csv という名前のファイルを書き込みモードで開き、列ヘッダー (テキスト、 著作者、 タグ) を定義し、ヘッダーをファイルに書き込み、 引用符 リストの各ディクショナリをCSVファイルに書き込みます。 csv.DictWriter は書式設定を処理するため、構造化データを簡単に保存できます。

Python標準ライブラリから、 random をインポートすることを忘れないでください:

import csv

ステップ7:すべてをまとめる

最終的なHTTPX Webスクレイピングスクリプトには次のものが含まれます:

import httpx
from bs4 import BeautifulSoup
import csv

# Make an HTTP GET request to the target page
response = httpx.get("http://quotes.toscrape.com")

# Access the HTML of the target page
html = response.text

# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")

# Where to store the scraped data
quotes = []

# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")

# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
    text = quote_element.find("span", class_="text").get_text().replace("“", "").replace("”", "")
    author = quote_element.find("small", class_="author").get_text()
    tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]

    # Store the scraped data
    quotes.append({
        "text": text,
        "author": author,
        "tags": tags
    })

# Specify the file name for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])

    # Write the header row
    writer.writeheader()

    # Write the scraped quotes data
    writer.writerows(quotes)

次のように実行します:

python scraper.py

Linux/macOSの場合は、次のように実行します:

python3 scraper.py

 quotes.csv ファイルがプロジェクトのルートフォルダに表示されます。それを開くと、次の事項が表示されます:

スクレイピングされたデータを含むCSV

完成です!HTTPXとBeautifulSoupを使用してWebスクレイピングを実行する方法を学習しました。

HTTPX Webスクレイピングの高度な機能とテクニック

基本的なシナリオでWebスクレイピングにHTTPXを使用する方法を理解したので、より複雑なユースケースで実際に動作する様子を確認する準備ができました。

以下の例では、ターゲットサイトは HttpBin.io /anything エンドポイントになります。これは、発信者から送信されたIPアドレス、ヘッダー、およびその他の情報を返す特殊なAPIです。

WebスクレイピングのHTTPXをマスターしましょう!

カスタムヘッダーの設定

HTTPX では ヘッダー 引数のため、 カスタムヘッダー を指定することができます:

import httpx

# Custom headers for the request
headers = {
    "accept": "application/json",
    "accept-language": "en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,es-US;q=0.6,es;q=0.5,it-IT;q=0.4,it;q=0.3"
}

# Make a GET request with custom headers
response = httpx.get("https://httpbin.io/anything", headers=headers)
# Handle the response...

カスタムユーザーエージェントを設定する

User-Agent は、Webスクレイピングの HTTPヘッダーの中で最も重要な1つです。デフォルトでは、HTTPX は次の ユーザーエージェントを使用します:

python-httpx/<VERSION>

この値により、リクエストが自動化されていることが簡単に明らかになり、ターゲットサイトによるブロックとなる可能性があります。

これを回避するには、次のようにカスタム User-Agent を設定して、実際のブラウザを模倣します:

import httpx

# Define a custom User-Agent
headers = {
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
}

# Make a GET request with the custom User-Agent
response = httpx.get("https://httpbin.io/anything", headers=headers)
# Handle the response...

Webスクレイピングに最適な ユーザーエージェントを発見しましょう!

Cookieを設定する

HTTPヘッダーと同様に、 引数 を使用して、HTTPXのCookieを設定できます:

import httpx

# Define cookies as a dictionary
cookies = {
    "session_id": "3126hdsab161hdabg47adgb",
    "user_preferences": "dark_mode=true"
}

# Make a GET request with custom cookies
response = httpx.get("https://httpbin.io/anything", cookies=cookies)
# Handle the response...

これにより、Webスクレイピングリクエストに必要なセッションデータを含めることができます。

プロキシ統合

 HTTPXリクエストをプロキシ経由でルーティングして あなたの身元を保護し、Webスクレイピングの実行中にIP禁止を回避します。これは、 プロキシ 引数を使用することで可能になります:

import httpx

# Replace with the URL of your proxy server
proxy = "<YOUR_PROXY_URL>"

# Make a GET request through a proxy server
response = httpx.get("https://httpbin.io/anything", proxy=proxy)
# Handle the response...

詳細については、プロキシでHTTPXを使用する方法 に関するガイドをご覧ください。

エラー処理

デフォルトでは、HTTPXは 接続またはネットワークの問題の場合にのみエラーを生成します。 4xx および 5xx ステータスコードを使用してHTTP応答に対しても例外を生成させるには、以下のように  raise_for_status () メソッドを使用します:

import httpx

try:
    response = httpx.get("https://httpbin.io/anything")
    # Raise an exception for 4xx and 5xx responses
    response.raise_for_status()
    # Handle the response...
except httpx.HTTPStatusError as e:
    # Handle HTTP status errors
    print(f"HTTP error occurred: {e}")
except httpx.RequestError as e:
    # Handle connection or network errors
    print(f"Request error occurred: {e}")

セッション処理

HTTPXでトップレベルAPIを使用する場合は、単一のリクエストごとに新しい接続が確立されます。つまり、TCP接続は再利用されません。ホストへのリクエストの数が増えると、このアプローチは非効率になります。

対照的に、 httpx.Client インスタンスを使用すると、 HTTP接続プーリングが有効になります。これは、同じホストへの複数のリクエストで、リクエストごとに新しいTCP接続を作成するのではなく、既存のTCP接続を再利用できることを意味します。

トップレベルAPIではなく、 クライアント を使用する利点は次のとおりです:

  • リクエスト間のレイテンシーの削減(ハンドシェイクの繰り返しを回避)
  • CPU使用率の低下とラウンドトリップの減少
  • ネットワークの混雑の軽減

さらに、 クライアント インスタンスは、以下を含むトップレベルのAPIでは利用できない機能によるセッション処理をサポートしています:

  • リクエスト全体におけるCookieの永続性。
  • すべての送信リクエストにおいて構成を適用。
  • HTTPプロキシ経由でリクエストを送信。

HTTPXで クライアント を使用するために推奨される方法は、コンテキストマネージャを使用することです( ステートメント):

import httpx

with httpx.Client() as client:
    # Make an HTTP request using the client
    response = client.get("https://httpbin.io/anything")

    # Extract the JSON response data and print it
    response_data = response.json()
    print(response_data)

または、クライアントを手動で管理し、 client.close ()を使用して接続プールを明示的に閉じることもできます:

import httpx

client = httpx.Client()
try:
    # Make an HTTP request using the client
    response = client.get("https://httpbin.io/anything")

    # Extract the JSON response data and print it
    response_data = response.json()
    print(response_data)
except:
  # Handle the error...
  pass
finally:
  # Close the client connections and release resources
  client.close()

注意リクエスト ライブラリに精通している場合、 Httpx.Client () は requests.Session ()と同様に機能します。

非同期API

デフォルトでは、HTTPXは標準の同期APIを公開します。同時に、必要な場合に備えて 非同期クライアント も提供しています。 asyncioを使用している場合、発信HTTPリクエストを効率的に送信するには、非同期クライアントの使用が不可欠です。

非同期プログラミングは、マルチスレッドよりも大幅に効率的なです。パフォーマンスが大幅に改善し、WebSocketといった長時間存続するネットワーク接続をサポートします。これは、 Webスクレイピングを高速化するための重要な要素です。

HTTPXで非同期リクエストを行うには、 AsyncClientが必要です。これを初期化し、以下に示すようにGETリクエストを行うために使用します:

import httpx
import asyncio

async def fetch_data():
    async with httpx.AsyncClient() as client:
        # Make an async HTTP request
        response = await client.get("https://httpbin.io/anything")

        # Extract the JSON response data and print it
        response_data = response.json()
        print(response_data)

# Run the async function
asyncio.run(fetch_data())

 with ステートメントにより、ブロックが終了したときにクライアントが自動的に閉じられるようになります。あるいは、クライアントを手動で管理する場合は、 await client.close ()により明示的にクライアントを閉じることができます。

 AsyncClientを使用する場合、すべてのHTTPXリクエストメソッド(get ()、 post ()など)は非同期であることに注意してください。そのため、応答を得るために呼び出す前に、 await を追加する必要があります。

失敗したリクエストを再試行する

Webスクレイピング中にネットワークが不安定になると、接続障害やタイムアウトが発生する場合があります。HTTPXでは、 HttpTransport インターフェース経由でこうした問題の処理を簡素化します 。このメカニズムは、 HTTpx.ConnectError または HTTpx.ConnectTimeout がが発生したときにリクエストを再試行します。

次の例は、リクエストを最大3回再試行するようにトランスポートを構成する方法を示しています:

import httpx

# Configure transport with retry capability on connection errors or timeouts
transport = httpx.HTTPTransport(retries=3)

# Use the transport with an HTTPX client
with httpx.Client(transport=transport) as client:
    # Make a GET request
    response = client.get("https://httpbin.io/anything")
    # Handle the response...

接続関連のエラーのみが再試行をトリガーすることに注意してください。読み取り/書き込みエラーや特定のHTTPステータスコードを処理するには、 tenacityのようなライブラリを使用してカスタム再試行ロジックを実装する必要があります。

HTTPXとWebスクレイピングのリクエスト

以下は、HTTPXと Webスクレイピングのリクエストを比較するサマリーテーブルです::

特徴 HTTPX リクエスト
GitHub Star 8k 52.4k
非同期サポート ✔️
接続プーリング ✔️ ✔️
HTTP/2サポート ✔️
ユーザーエージェントのカスタマイズ ✔️ ✔️
プロキシサポート ✔️ ✔️
Cookieの取り扱い ✔️ ✔️
タイムアウト 接続と読み取りはカスタマイズ可能 接続と読み取りはカスタマイズ可能
再試行のメカニズム トランスポート経由で利用可能  HTTPAdapters経由で利用可能
パフォーマンス
コミュニティのサポートと人気 成長

まとめ

この記事では、Webスクレイピングの httpx ライブラリについて説明しました。それが何であり、何を提供するか、その利点について理解しました。HTTPXは、オンラインデータを収集するときにHTTPリクエストを行うための高速で信頼性の高いオプションです。

問題は、自動化されたHTTPリクエストによってパブリックIPアドレスが明らかになり、身元や位置情報が漏洩する可能性があることです。それはあなたのプライバシーを侵害します。セキュリティとプライバシーを強化する最も効果的な方法の1つは、プロキシサーバーを使用して IPアドレスを隠すことです

Bright Dataは世界最高レベルのプロキシサーバーを保有しており、フォーチュン500企業を含む20,000社以上の顧客にサービスを提供しています。Bright Dataは次のような様々な種類のプロキシを提供しています:

  • データセンタープロキシ  — 77万件を超えるデータセンターIP
  • 住宅用プロキシ  — 195ヵ国以上、7200万件を超える住宅用IP
  • ISPプロキシ  — 70万件を超えるISP用IP
  • モバイルプロキシ  — 700万件を超えるモバイル用IP

今すぐ無料のBright Dataアカウントを作成して、スクレイピングのソリューションとプロキシを試してください!

クレジットカードは必要ありません