注目キーワード
  1. Python
  2. コンペ

Python requests Session getの使い方完全ガイド!パフォーマンス向上の5つのメリット

  • 2025年6月17日
  • 2025年6月17日
  • Python
  • 3回
  • 0件

「PythonでAPIアクセスしてるけど、毎回新しい接続を作るのは無駄な気がする…」「大量のHTTPリクエストが遅くて困っている」そんな悩みを抱えていませんか?

実は、requests.Session()を使うことで、アプリケーションのパフォーマンスを大幅に向上させることができます。特に複数のHTTPリクエストを送信する場合、TCP接続の再利用により最大90%の処理時間短縮が可能です。

この記事では、requests.Session().get()の基本的な使い方から実践的な活用法まで、具体的なコード例とともに詳しく解説します。読み終わる頃には、効率的なHTTP通信を実装できるようになるでしょう。

requests.get()とrequests.Session().get()の基本的な違い

PythonでHTTPリクエストを送信する際、requests.get()requests.Session().get()には重要な違いがあります。この違いを理解することが、パフォーマンス向上への第一歩です。

接続方式の違い:短い接続 vs 持続的接続

requests.get()は、リクエストごとに新しいセッションオブジェクトを作成し、リクエスト完了後に即座に接続を切断します。一方、requests.Session().get()は一度確立したTCP接続を維持し、複数のリクエストで再利用します。

import requests

# 毎回新しい接続を作成(非効率)
response1 = requests.get('https://api.example.com/data1')
response2 = requests.get('https://api.example.com/data2')

# 接続を再利用(効率的)
session = requests.Session()
response1 = session.get('https://api.example.com/data1')
response2 = session.get('https://api.example.com/data2')

パフォーマンスに与える影響

実際のベンチマークテストでは、同一サーバーへの10,000回のリクエストにおいて以下の結果が報告されています:

  • requests.get()使用時:38.56秒
  • requests.Session()使用時:3.06秒

この差は、TCP接続の確立とハンドシェイクにかかるオーバーヘッドによるものです。Session使用により、約90%の処理時間短縮が実現されています。

メモリ使用量の比較

Sessionオブジェクトは接続プール(デフォルトで10接続)を管理するため、わずかなメモリオーバーヘッドが発生します。しかし、大量のリクエストを処理する場合、全体的なリソース効率は大幅に改善されます。

requests.Sessionを使うべき5つのメリット

1. TCP接続の再利用による高速化

同一ホストへの複数リクエストで、既存のTCP接続を再利用できます。これにより、接続確立のオーバーヘッド(通常50-100ms)を削減できます。

import time
import requests

# 接続再利用なし
start = time.time()
for i in range(10):
    requests.get('https://httpbin.org/delay/0')
print(f"通常のrequests: {time.time() - start:.2f}秒")

# 接続再利用あり
start = time.time()
session = requests.Session()
for i in range(10):
    session.get('https://httpbin.org/delay/0')
print(f"Session使用: {time.time() - start:.2f}秒")

2. Cookie情報の自動保持

Sessionオブジェクトは、レスポンスで受信したCookieを自動的に保存し、次回のリクエストで送信します。ログイン状態の維持に特に有効です。

session = requests.Session()

# ログイン処理
login_data = {'username': 'user', 'password': 'pass'}
session.post('https://example.com/login', data=login_data)

# ログイン状態が保持されたままアクセス
protected_data = session.get('https://example.com/protected')

3. リクエスト設定の共通化

ヘッダー、認証情報、タイムアウト設定などを一度設定すれば、全てのリクエストに適用されます。

session = requests.Session()
session.headers.update({
    'User-Agent': 'MyApp/1.0',
    'Accept': 'application/json'
})
session.auth = ('username', 'password')

# すべてのリクエストに共通設定が適用される
response1 = session.get('https://api.example.com/endpoint1')
response2 = session.get('https://api.example.com/endpoint2')

4. セキュリティ向上

SSL/TLS設定の一元管理により、セキュリティポリシーの一貫性を保てます。

session = requests.Session()
session.verify = '/path/to/cert.pem'  # 証明書検証
session.cert = ('/path/to/client.cert', '/path/to/client.key')  # クライアント証明書

5. リソース効率の最適化

接続プールにより、システムリソースの効率的な利用が可能になります。

Session getの基本的な使い方と実装例

基本的なSessionオブジェクトの作成

import requests

# Sessionオブジェクトの作成
session = requests.Session()

# GETリクエストの実行
response = session.get('https://api.example.com/data')
print(response.json())

# セッションのクローズ(明示的に行う場合)
session.close()

with文を使った適切なリソース管理

推奨される方法は、with文を使用したコンテキストマネージャーの活用です:

import requests

with requests.Session() as session:
    # リクエスト処理
    response = session.get('https://api.example.com/data')
    print(response.status_code)
    
    # with文を抜ける際に自動的にセッションがクローズされる

共通設定の適用方法

with requests.Session() as session:
    # 共通ヘッダーの設定
    session.headers.update({
        'Authorization': 'Bearer your-token',
        'Content-Type': 'application/json'
    })
    
    # タイムアウト設定
    session.timeout = 10
    
    # プロキシ設定
    session.proxies.update({
        'http': 'http://proxy.example.com:8080',
        'https': 'https://proxy.example.com:8080'
    })
    
    response = session.get('https://api.example.com/data')

実践的なコード例で学ぶSession活用法

API連続アクセスの高速化例

import requests
import time

def fetch_user_data_without_session(user_ids):
    """Session未使用の例"""
    results = []
    start_time = time.time()
    
    for user_id in user_ids:
        response = requests.get(f'https://api.example.com/users/{user_id}')
        results.append(response.json())
    
    print(f"Session未使用: {time.time() - start_time:.2f}秒")
    return results

def fetch_user_data_with_session(user_ids):
    """Session使用の例"""
    results = []
    start_time = time.time()
    
    with requests.Session() as session:
        for user_id in user_ids:
            response = session.get(f'https://api.example.com/users/{user_id}')
            results.append(response.json())
    
    print(f"Session使用: {time.time() - start_time:.2f}秒")
    return results

# 使用例
user_ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data1 = fetch_user_data_without_session(user_ids)
data2 = fetch_user_data_with_session(user_ids)

ログインが必要なサイトへのアクセス

import requests

def scrape_protected_content():
    with requests.Session() as session:
        # ログイン処理
        login_url = 'https://example.com/login'
        login_data = {
            'username': 'your_username',
            'password': 'your_password',
            'csrf_token': 'token_value'
        }
        
        # ログインページでCSRFトークンを取得
        login_page = session.get(login_url)
        # CSRFトークンの抽出ロジック(BeautifulSoupなどを使用)
        
        # ログイン実行
        login_response = session.post(login_url, data=login_data)
        
        if login_response.status_code == 200:
            # ログイン成功後、保護されたページにアクセス
            protected_url = 'https://example.com/protected-data'
            data_response = session.get(protected_url)
            return data_response.text
        else:
            print("ログインに失敗しました")
            return None

# 使用例
content = scrape_protected_content()

パフォーマンス最適化のベストプラクティス

接続プール設定の調整

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def create_optimized_session():
    session = requests.Session()
    
    # リトライ戦略の設定
    retry_strategy = Retry(
        total=3,
        backoff_factor=1,
        status_forcelist=[429, 500, 502, 503, 504],
    )
    
    # HTTPアダプターの設定
    adapter = HTTPAdapter(
        pool_connections=20,  # 接続プール数
        pool_maxsize=20,      # プール内の最大接続数
        max_retries=retry_strategy
    )
    
    session.mount("http://", adapter)
    session.mount("https://", adapter)
    
    return session

# 使用例
session = create_optimized_session()

タイムアウト設定の重要性

import requests
from requests.exceptions import Timeout, RequestException

def safe_request_with_timeout(url, timeout=(5, 10)):
    """
    安全なリクエスト実行
    timeout=(接続タイムアウト, 読み取りタイムアウト)
    """
    try:
        with requests.Session() as session:
            response = session.get(url, timeout=timeout)
            response.raise_for_status()
            return response.json()
    except Timeout:
        print(f"タイムアウトが発生しました: {url}")
        return None
    except RequestException as e:
        print(f"リクエストエラー: {e}")
        return None

# 使用例
data = safe_request_with_timeout('https://api.example.com/slow-endpoint')

よくある問題と解決方法

セッションが切れる問題への対処

import requests
import time

class PersistentSession:
    def __init__(self, base_url):
        self.base_url = base_url
        self.session = None
        self.last_activity = None
        self.session_timeout = 300  # 5分
    
    def get_session(self):
        current_time = time.time()
        
        # セッションが存在しない、または期限切れの場合は新規作成
        if (self.session is None or 
            self.last_activity is None or 
            current_time - self.last_activity > self.session_timeout):
            
            if self.session:
                self.session.close()
            
            self.session = requests.Session()
            self.authenticate()  # 再認証
        
        self.last_activity = current_time
        return self.session
    
    def authenticate(self):
        """認証処理(必要に応じて実装)"""
        # ログイン処理やAPI Keyの設定など
        self.session.headers.update({
            'Authorization': 'Bearer your-token'
        })
    
    def get(self, endpoint, **kwargs):
        session = self.get_session()
        url = f"{self.base_url}/{endpoint}"
        return session.get(url, **kwargs)

# 使用例
api = PersistentSession('https://api.example.com')
response = api.get('users/1')

メモリリークを避ける方法

Sessionオブジェクトは使用後に必ずクローズし、リソースの適切な解放を行うことが重要です。with文の使用やSessionManagerクラスによる管理を推奨します。

マルチスレッド環境での注意点

requests.Sessionはスレッドセーフではありません。マルチスレッド環境では、各スレッドで独立したSessionオブジェクトを使用するか、ThreadLocalStorageを活用してください。

まとめ

requests.Session().get()は、Pythonでの効率的なHTTP通信を実現する強力なツールです。特に以下のような場面で威力を発揮します:

  • 同一サーバーへの複数リクエスト
  • ログイン状態の維持が必要な処理
  • 大量データの取得処理
  • APIの連続アクセス

この記事で紹介した5つのメリットを理解し、適切な設定とエラーハンドリングを組み合わせることで、パフォーマンスとセキュリティの両方を向上させることができます。ぜひこの記事の内容を参考に、あなたのPythonアプリケーションをより効率的にしてください。

最新情報をチェックしよう!