コンテンツにスキップ

HTTPX と Python を使用して Web スクレイピングを行う方法

Web スクレイピングは、Web サイトからデータを自動的に抽出するプロセスです。これは、分析や機械学習などのために大量のデータを収集するために使用される一般的な手法です。 Python には、Web スクレイピングを簡単にする優れたライブラリが多数あります。一般的なオプションの 1 つは HTTPX です。

HTTPX は、Python 用の強力で最新の HTTP クライアントです。これは Requests の開発者によって作成され、Requests から多くのインスピレーションを得ていると同時に、HTTP/2 サポートなどの新機能も追加されています。

この包括的なガイドでは、HTTPX を使用して Python で Web サイトを効果的にスクレイピングする方法を説明します。

HTTPX を始める

まず、HTTPX を pip 経由でインストールできます。

pip install httpx

あるいは、詩を使用することもできます。

poetry add httpx

インストールすると、HTTPX をインポートして使用できます。

import httpx

response = httpx.get(‘https://example.com‘)
print(response.text)

これにより、example.com への GET リクエストが作成され、ホームページの HTML が出力されます。

HTTPX にはシンプルな API があり、GET、POST、PUT、DELETE、HEAD、OPTIONS などの一般的な HTTP 動詞をすべてサポートしています。

主な機能は次のとおりです。

  • HTTP/1.1 および HTTP/2 のサポート
  • 非同期 aiohttp スタイル API
  • 接続プーリングとキープアライブ
  • プロキシサポート
  • タイムアウト設定
  • クッキーの永続性
  • 使い慣れたリクエスト形式の API

次に、一般的な使用パターンをいくつか見てみましょう。

HTTPX でリクエストを行う

GET リクエストを行うには、 httpx.get() メソッドを使用できます:

response = httpx.get(‘https://example.com‘)

同様に、 httpx.post(), httpx.put(), httpx.delete()、などは他の HTTP 動詞に使用できます。

ヘッダー、Cookie、タイムアウトなどのパラメーターをキーワード引数として渡すことができます。

response = httpx.get(
  ‘https://httpbin.org/headers‘,
  headers = {
    ‘User-Agent‘: ‘MyBot 1.0‘
  },
  timeout = 10.0
)

応答には次のようなプロパティが含まれます status_code, headers, text, json()、その他:

print(response.status_code)
print(response.headers)
print(response.text)
json = response.json()

応答オブジェクトを反復処理することで、応答を段階的にストリーミングすることもできます。

HTTPXクライアントの使用

ほとんどのスクレイピング タスクでは、永続的なタスクを使用することをお勧めします。 httpx.Client インスタンス。

クライアントは、複数のリクエストにわたって接続プーリング、セッション、Cookie などを処理します。

import httpx

client = httpx.Client()

response = client.get(‘https://example.com‘)
print(response.text)

response = client.get(‘https://httpbin.org/cookies/set?name=foo‘)
print(response.text) 

response = client.get(‘https://httpbin.org/cookies‘)
print(response.json())

ここでは、Cookie の永続化を自動的に処理する同じクライアントを使用して複数のリクエストを作成します。

クライアントの作成時に、ヘッダー、プロキシ、認証などのオプションを構成することもできます。

client = httpx.Client(
  headers = {
    ‘User-Agent‘: ‘MyBot 1.0‘,
    ‘Authorization‘: ‘Bearer xxx‘   
  },
  proxies = ‘http://192.168.1.1:8181/‘,
  auth = (‘username‘, ‘password‘)
)

次に、非同期でリクエストを行う方法を見てみましょう。

HTTPX を使用した非同期リクエスト

Python で非同期にリクエストを行うために、HTTPX は AsyncClient:

import httpx

async with httpx.AsyncClient() as client:
  response = await client.get(‘https://example.com‘) 

を使用しております async with クライアントを初期化するには、 await リクエストに応じて実行し、その後クライアントを自動的に閉じます。

複数の URL を同時にスクレイピングするには、次を使用できます asyncio.gather():

import httpx
import asyncio

async def get_url(url):
  async with httpx.AsyncClient() as client:
    response = await client.get(url)
    return response.text

urls = [‘https://example.com‘, ‘https://httpbin.org‘, ‘https://python.org‘]

async def main():
  responses = await asyncio.gather(*[get_url(url) for url in urls])
  print(responses)

asyncio.run(main())

asyncio.gather() 複数のコルーチンを同時に待機し、待機可能な順序で結果を返します。

などの他のオプションもあります asyncio.as_completed() 完了時に処理するには:

tasks = [get_url(url) for url in urls]

async def main():
  for result in asyncio.as_completed(tasks):
    print(await result)

非同期 IO を使用すると、一度に複数のページを同時にフェッチできるため、スクレイピングの高速化に役立ちます。

次に、HTML および JSON 応答からのデータのスクレイピングを見てみましょう。

HTML および JSON 応答のスクレイピング

HTML スクレイピングの場合、Beautiful Soup のようなパーサーを使用してデータを抽出できます。

from bs4 import BeautifulSoup

response = httpx.get(‘https://en.wikipedia.org/wiki/Python_(programming_language)‘)

soup = BeautifulSoup(response.text, ‘html.parser‘)

for link in soup.select(‘.toctext‘):
  print(link.text.strip())

これにより、Wikipedia ページの目次の内容が印刷されます。

JSON 応答の場合、HTTPX は組み込みの .json() 方法:

response = httpx.get(‘https://api.github.com/repos/encode/httpx‘)

json = response.json()
print(json[‘description‘])

  json= パラメータを使用して、リクエスト内の JSON データをシリアル化することもできます。

パーサーと連携して、API や Web サイトからデータを抽出するスクレイパーを構築できます。

問題とエラーの処理

スクレイピング中に、接続エラー、タイムアウト、レート制限などの問題が頻繁に発生します。

HTTPX は例外と、それらを適切に処理するためのツールを提供します。

タイムアウト

遅い応答を処理するには、カスタムの timeout パラメータ。デフォルトは 5 秒です。

response = httpx.get(‘https://example.com‘, timeout=10.0) 

これを超えると、 httpx.TimeoutException 発生:

try:
  response = httpx.get(‘https://example.com‘, timeout=0.001)
except httpx.TimeoutException:
  print(‘Request timed out‘)

特定のサイトまたはページでは、より長いタイムアウトが必要になる場合があります。

HTTPエラー

400、500 などの HTTP エラーの場合、 response.raise_for_status() メソッドを使用できます:

try:
  response = httpx.get(‘https://httpbin.org/status/500‘)
  response.raise_for_status()
except httpx.HTTPStatusError:
  print(‘HTTP Error occurred‘)  

これにより、4xx または 5xx ステータス コードで例外が発生します。

リクエストの再試行

再試行ロジックを追加するには、次のような外部パッケージを使用します。 tenacity に使える:

from tenacity import retry, stop_after_attempt

@retry(stop=stop_after_attempt(3))
def make_request():
  response = httpx.get(‘https://example.com‘)
  response.raise_for_status()
  return response.json()

data = make_request()

ここでは、例外が発生した場合に最大 3 回再試行します。より高度な再試行ロジックも定義できます。

並列リクエストの制限

多くのリクエストを並行して実行すると、接続制限が発生する可能性があります。

  limits パラメータを使用して、最大接続数などのオプションを構成できます。

client = httpx.AsyncClient(
  limits = httpx.Limits(max_connections=20)
)

ターゲット サイトに基づいてこのパラメーターを調整すると、制限を回避するのに役立ちます。

これらの一般的な問題に対処することで、より弾力性のあるスクレーパーを構築できます。

スクレイピングのベストプラクティス

HTTPX を使用して効果的な Web スクレイパーを作成するためのヒントをいくつか紹介します。

  • HTTPX クライアントを使用する – クライアントは、接続プーリング、Cookie の永続性、その他の利点を提供します。

  • 丁寧にこする – リクエストレートを制限して、サーバーに負荷がかかるのを防ぎます。ランダムな遅延とスロットルを使用します。

  • エラーの処理 – try/excel ブロッ​​ク、ステータス チェック、および再試行を使用して問題を処理します。

  • 非同期 IO を使用する – 速度を向上させるためにページを同時にスクレイピングします。ただし、禁止を避けるために同時実行を制限します。

  • ユーザーエージェントをランダム化する – ランダムなユーザー エージェント文字列を回転させて、より人間らしく見えるようにします。

  • プロキシの使用 – 異なるプロキシ/IP をローテーションしてリクエストを分散します。

  • データをキャッシュして永続化する – 再スクレイピングを避けるために、スクレイピングされたデータをファイル/データベースに保存します。

このようなベスト プラクティスに従うことで、より堅牢で保守しやすいスクレーパーを構築できます。

高度なスクレイピング技術

HTTPX のさらに高度なスクレイピング機能をいくつか見てみましょう。

認証ページのスクレイピング

認証されたページをスクレイピングするために、HTTPX はベーシック、ダイジェスト、ベアラー認証などの複数の認証タイプをサポートしています。

client = httpx.Client(
  auth = (‘username‘, ‘password‘)
)

response = client.get(‘https://api.example.com/users/me‘)

認証資格情報はリクエスト間で自動的に保持されます。

クッキーの取り扱い

  cookies パラメータを使用してカスタム Cookie を送信できます。

client = httpx.Client(
  cookies = {
    ‘sessionId‘: ‘xxxx‘
  }
)

response = client.get(‘https://example.com/dashboard‘) 

また、サーバーによって設定された Cookie はクライアントに自動的に保持されます。

ストリーミング応答

大規模な応答の場合は、応答オブジェクトを反復処理することで段階的にストリーミングできます。

response = client.get(‘https://example.com/bigfile‘)
for chunk in response:
  process(chunk) 

これにより、応答全体をメモリにロードする必要がなくなります。

プロキシサポート

プロキシ サーバー経由でリクエストをルーティングするには、 proxies パラメータを使用できます:

proxy = ‘http://192.168.0.1:8888‘ 

client = httpx.Client(proxies = {‘http‘: proxy, ‘https‘: proxy})

異なるプロキシをローテーションすると、異なる IP からのリクエストを分散するのに役立ちます。

カスタムヘッダー

ユーザー エージェントのようにリクエスト ヘッダーをスプーフィングまたはランダム化することができます。

client = httpx.Client(headers = {
  ‘User-Agent‘: ‘MyBot 1.0‘ 
})

これは実際のブラウザのヘッダーを模倣しています。

これらのより高度な機能により、HTTPX と Python を使用して堅牢なスクレイパーを構築できます。

スクレーパーの例

次に、HTTPX を使用して構築されたスクレイパーの例をいくつか見てみましょう。

Reddit APIスクレーパー

Reddit API の基本的なスクレイパーは次のとおりです。

import httpx

client = httpx.Client()

subreddit = ‘python‘ 
listing = ‘hot‘
limit = 10

response = client.get(f‘https://www.reddit.com/r/{subreddit}/{listing}.json?limit={limit}‘)

data = response.json()[‘data‘]

for post in data[‘children‘]:
   title = post[‘data‘][‘title‘]
   score = post[‘data‘][‘score‘]
   print(f"{title} (Score: {score})")

これにより、Python サブレディットから上位の投稿のデータが取得されます。 API は解析できる JSON を返します。

このスクレイパーを拡張して、複数のサブレディットからデータを抽出したり、結果をデータベースに保存したりすることができます。

ニュース記事スクレーパー

以下は、サイトから記事を抽出するシンプルなニュース スクレーパーです。

from bs4 import BeautifulSoup
import httpx

client = httpx.Client()

response = client.get("https://example.com/news")
soup = BeautifulSoup(response.text, ‘html.parser‘)

for article in soup.select(‘.article‘):

  title = article.select_one(‘.article-title‘).text
  content = article.select_one(‘.article-content‘).text

  print(title) 
  print(content)
  print() 

これはすべてを見つけます .article 要素を抽出し、タイトルとコンテンツのフィールドを抽出して、記事を印刷します。

これも、追加フィールドの取得、日付の解析、データベースへの保存などに拡張できます。

検索結果 スクレーパー

ここでは、Google 検索結果のスクレーパーの例を示します。

import httpx

query = "httpx python"
url = f"https://www.google.com/search?q={query}"

client = httpx.Client()
response = client.get(url)

from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, ‘html.parser‘)

for result in soup.select(‘.tF2Cxc‘):

  title = result.select_one(‘.DKV0Md‘).text
  link = result.select_one(‘.yuRUbf a‘)[‘href‘]

  print(title)
  print(link) 
  print()

これは、Google で特定のクエリを検索し、結果のリンク/タイトルを解析して出力します。

ここでも、検索結果数の抽出、フィールドの追加、結果ページのスクレイピング、キャプチャの検出など、多くの機能強化が可能です。

これらの例は、HTTPX を使用した一般的なスクレイピング パターンを示しています。同じ手法を適用して、多くの Web サイトや API のスクレイパーを構築できます。

まとめ

要約すると、HTTPX は、Python Web スクレイパーを構築するための強力な HTTP クライアントを提供します。いくつかの重要なポイントを次に示します。

  • HTTPX には、リクエストを作成するためのシンプルなリクエスト スタイルの API があります。

  • 非同期サポートにより、リクエストを同時に行うことができます。

  • タイムアウト、再試行、ステータスチェックによる堅牢なエラー処理。

  • Beautiful Soup と JSON API を使用して HTML ページを簡単にスクレイピングします。

  • 永続クライアントは、接続プーリング、セッション、Cookie 処理を提供します。

  • プロキシ、ヘッダー、認証などの高度な技術により、高度なスクレイパーが可能になります。

  • スロットリング、ランダムな遅延、ユーザー エージェントの使用などのベスト プラクティスに従ってください。

HTTPX を使用すると、Python でスクレイピングを簡単に開始できます。堅牢なエラー処理と非同期同時実行性を備えた、スケーラブルなスクレーパーを開発できます。

次の Python Web スクレイピング プロジェクトで HTTPX を試してみてください。

タグ:

参加する

あなたのメールアドレスは公開されません。 必須フィールドは、マークされています *