【Python】requestsライブラリを使いこなす!webスクレイピング&API連携の基本と実践テクニック

PythonでのHTTP通信に欠かせないrequestsライブラリ。webスクレイピングやAPIとの連携に活用できるこのライブラリの使い方を、基本からマルチスレッド・非同期処理まで網羅的に解説します。

この記事を読んだらわかること
  • requestsライブラリの基本的な使い方
  • webスクレイピングの手法とBeautiful Soupとの連携
  • Web APIとの連携方法
  • マルチスレッド・非同期処理による高速化
  • エラー対策とデバッグ手法

Pythonのrequestsライブラリとは?特徴と基本的な使い方を解説!

Pythonでwebスクレイピングや、APIを利用したデータ収集を行う際に欠かせないのが、HTTP通信を行うためのライブラリです。中でも、requestsは最も人気のあるサードパーティ製ライブラリの1つです。この記事では、requestsの概要と特徴、インストール方法、基本的な使い方について解説します。

requestsの概要 – シンプルで強力なHTTP通信ライブラリ

requestsは、Pythonの標準ライブラリであるurllibやurllib2と比べて、よりシンプルで直感的なAPIを提供しているのが特徴です。HTTP通信に必要な機能を網羅しつつ、わかりやすいメソッドやパラメータの命名で、Pythonでの開発経験が浅い方にも使いやすいライブラリとなっています。

主な特徴は以下の通りです。

  • URLを指定してGET/POST/PUT/DELETEリクエストを送信し、レスポンスを取得できる
  • 認証、クッキー、セッション、タイムアウト、リダイレクトなどの機能に対応
  • リクエストヘッダやクエリパラメータの指定が簡単
  • レスポンスデータをJSON形式で取得可能

webスクレイピングやAPIとの連携を行う際は、ほとんどの場合でrequestsを使用すると言っても過言ではありません。

requestsのインストールと基本的な使用法

requestsは外部ライブラリであるため、別途インストールが必要です。pipまたはcondaを使って、以下のようにインストールできます。

# pipの場合
pip install requests

# Anacondaの場合
conda install requests

インストールが完了したら、以下のようにrequestsをインポートして使用します。

import requests

# GETリクエストを送信し、レスポンスを取得する
response = requests.get('https://example.com')

# レスポンスのステータスコードを確認する
print(response.status_code)  # 200 (OK)

# レスポンスのHTMLを取得する
print(response.text)

requestsでは、get()post()put()delete()といったメソッドを使って、それぞれのHTTPメソッドに対応したリクエストを送信します。リクエストの際に、URLを第一引数に指定します。

レスポンスはResponseオブジェクトとして返され、ステータスコードやレスポンスボディ、ヘッダー情報などにアクセスできます。

requestsを使えば、webページのHTMLを取得してスクレイピングしたり、RESTful APIからJSONデータを取得して処理したりと、多様な用途に活用できます。次章以降で、より実践的な使い方を見ていきましょう。

requestsを使ったwebスクレイピングの基本とポイント

requestsを使えば、webページのHTMLを取得し、必要な情報を抽出するwebスクレイピングを行うことができます。この章では、requestsを使ったwebスクレイピングの基本的な流れと、クッキーやセッション、認証、ヘッダー、パラメータなどの扱い方、エラーハンドリングやリトライ処理の実装方法について解説します。

requestsでwebページのHTMLを取得する方法

webスクレイピングの第一歩は、対象のwebページのHTMLを取得することです。requestsを使うと、以下のようにシンプルなコードでHTMLを取得できます。

import requests

url = 'https://example.com'
response = requests.get(url)

if response.status_code == 200:
    html = response.text
    print(html)
else:
    print(f'Error: {response.status_code}')

requests.get()でGETリクエストを送信し、response.textでHTMLを取得します。response.status_codeでステータスコードを確認し、200(OK)以外の場合はエラー処理を行います。

取得したHTMLのエンコーディングは、response.encodingで指定できます。

クッキーやセッション、認証の扱い方

webサイトによっては、クッキーやセッションを維持したり、認証が必要だったりします。requestsでは、以下のような方法で対応できます。

セッションを維持する場合は、requests.Sessionを使用します。

session = requests.Session()
session.get(url)

クッキーを送信する場合は、cookiesパラメータを使用します。

cookies = {'session_id': 'abcdefg'}
response = requests.get(url, cookies=cookies)

Basic認証が必要な場合は、authパラメータを使用します。

auth = ('username', 'password')
response = requests.get(url, auth=auth)

ヘッダーやパラメータの設定のコツ

リクエストを送信する際、ヘッダーやパラメータを適切に設定することが重要です。

ヘッダーを設定する場合は、headersパラメータを使用します。

headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)

クエリパラメータを設定する場合は、paramsパラメータを使用します。

params = {'page': 1, 'limit': 10}
response = requests.get(url, params=params)

POSTリクエストでデータを送信する場合は、dataパラメータやjsonパラメータを使用します。

data = {'username': 'john', 'password': 'secret'}
response = requests.post(url, data=data)

エラーハンドリングとリトライ処理の実装

webスクレイピングを行う際は、エラーハンドリングとリトライ処理を実装することが重要です。

ステータスコードが200以外の場合は、適切にエラー処理を行います。

if response.status_code != 200:
    raise ValueError(f'Error: {response.status_code}')

リトライ処理を実装する場合は、max_retriesパラメータとbackoff_factorパラメータを使用します。

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

retry_strategy = Retry(
    total=3,
    status_forcelist=[500, 502, 503, 504],
    backoff_factor=1
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.mount('https://', adapter)
session.mount('http://', adapter)

response = session.get(url)

タイムアウトを設定する場合は、timeoutパラメータを使用します。

response = requests.get(url, timeout=10)

webスクレイピングを行う際は、Robots.txtを確認し、クロールディレイを設定することも大切です。また、サーバーへの負荷を考慮し、適切な間隔でリクエストを送信するようにしましょう。

import time

time.sleep(1)  # 1秒待機

スクレイピングの際は、著作権や利用規約に十分注意し、違法行為とならないよう気を付けてください。

requestsを使えば、シンプルなコードでwebスクレイピングを行うことができます。この章で紹介した内容を踏まえて、効率的で正確なスクレイピングを目指しましょう。

requestsとBeautiful Soupを組み合わせたスクレイピングテクニック

requestsでwebページのHTMLを取得したら、次はBeautiful Soupを使ってHTMLを解析し、必要なデータを抽出します。Beautiful SoupはPythonの強力なHTMLパーサーライブラリで、HTMLやXMLからデータを抽出するために広く使われています。この章では、requestsとBeautiful Soupを組み合わせたスクレイピングの基本的な流れと、タグ、クラス、idを指定した要素の抽出方法、表形式データの抽出とpandasでのデータ加工、JavaScriptで動的に生成される要素の取得方法について解説します。

Beautiful Soupでタグ・クラス・idを指定して要素を抽出

Beautiful Soupを使うには、まずpipでインストールします。

pip install beautifulsoup4

インストールが完了したら、以下のようにBeautiful Soupをインポートして使用します。

import requests
from bs4 import BeautifulSoup

url = 'https://example.com'
response = requests.get(url)

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

# タグ名を指定して要素を抽出
title = soup.find('h1').text
print(title)

# class属性を指定して要素を抽出
content = soup.find('div', class_='content').text
print(content)

# id属性を指定して要素を抽出
footer = soup.find('footer', id='main-footer').text
print(footer)

find()find_all()を使って、タグ名、class属性、id属性などを指定して要素を抽出できます。text属性を使うと、要素のテキストを取得できます。

セレクターを使って要素を抽出することもできます。

# セレクターを使って要素を抽出
links = soup.select('ul.menu > li > a')
for link in links:
    print(link.get('href'))

表形式データの抽出とpandasでのデータ加工

webページ上の表形式データをスクレイピングする際は、以下のようにBeautiful Soupとpandasを組み合わせると便利です。

import pandas as pd

# 表形式データを抽出
table = soup.find('table', class_='data')

# データフレームに変換
df = pd.read_html(str(table))[0]

# データの加工と保存
df['売上'] = df['売上'].str.replace(',', '').astype(int)
df.to_csv('data.csv', index=False)

read_html()を使うと、HTMLの<table>タグからデータフレームを作成できます。データフレームに変換した後は、pandasの機能を使ってデータを加工したり、CSVファイルに保存したりできます。

JavaScriptで動的に生成される要素の取得方法

JavaScriptで動的に生成される要素をスクレイピングする場合は、Selenium、Puppeteer、Splashなどのヘッドレスブラウザを使用します。ここでは、Seleniumを使った例を紹介します。

from selenium import webdriver
from bs4 import BeautifulSoup

url = 'https://example.com'

# ChromeDriverを使用
driver = webdriver.Chrome()
driver.get(url)

# JavaScriptのレンダリング後のHTMLを取得
html = driver.page_source

# Beautiful Soupでデータを抽出
soup = BeautifulSoup(html, 'html.parser')
elements = soup.select('div.dynamic-content')

for element in elements:
    print(element.text)

driver.quit()

Seleniumを使うと、JavaScriptのレンダリング後のHTMLを取得できます。取得したHTMLをBeautiful Soupに渡せば、通常のスクレイピングと同様にデータを抽出できます。

requestsとBeautiful Soupを組み合わせることで、効率的にwebスクレイピングを行うことができます。pandasやSeleniumなどのライブラリと一緒に使えば、さらに高度なスクレイピングも可能です。ただし、スクレイピングを行う際は、webサイトの利用規約を確認し、適切な方法で行うようにしましょう。

requestsを使ってWeb APIと連携する方法

Web APIは、アプリケーション同士がネットワーク経由で情報をやり取りするための仕組みです。HTTPプロトコルを使用して、JSON、XML、テキストなどのデータ形式でデータを送受信します。この章では、requestsを使ったWeb APIとの連携方法について解説します。GET/POST/PUT/DELETEリクエストの送信方法、JSONデータの取得とデータ構造の理解、認証が必要なAPIの使用方法などを紹介します。

GET/POST/PUT/DELETEリクエストの送信方法

requestsを使えば、簡単にWeb APIにリクエストを送信できます。以下は、APIにGETリクエストを送信する例です。

import requests

url = 'https://api.example.com/users'
response = requests.get(url)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f'Error: {response.status_code}')

requests.get()を使ってGETリクエストを送信し、response.status_codeでステータスコードを確認します。ステータスコードが200の場合は、response.json()でJSONデータを取得します。

POST、PUT、DELETEリクエストを送信する場合は、以下のようにrequests.post()requests.put()requests.delete()を使用します。

# POSTリクエスト
data = {'name': 'John', 'email': 'john@example.com'}
response = requests.post(url, data=data)

# PUTリクエスト
data = {'name': 'John Smith'}
response = requests.put(url + '/1', data=data)

# DELETEリクエスト
response = requests.delete(url + '/1')

JSONデータの取得とデータ構造の理解

APIのレスポンスとしてよく使われるJSONデータは、Pythonの辞書やリストを使って操作できます。

# JSONデータの例
{
  "users": [
    {
      "id": 1,
      "name": "John",
      "email": "john@example.com"
    },
    {
      "id": 2,
      "name": "Alice",
      "email": "alice@example.com"
    }
  ]
}

上記のようなJSONデータを取得した場合、以下のようにデータを操作できます。

data = response.json()

# ユーザー数を取得
user_count = len(data['users'])

# 各ユーザーの名前を取得
for user in data['users']:
    print(user['name'])

認証付きAPIの使用法 – API KeyとAccess Tokenの取得と利用

多くのAPIでは、認証が必要です。API KeyやAccess Tokenを取得し、リクエストヘッダーやパラメータに含めて送信します。

url = 'https://api.example.com/users'
api_key = 'your_api_key'

headers = {
    'Authorization': f'Bearer {api_key}'
}

response = requests.get(url, headers=headers)

上記の例では、AuthorizationヘッダーにAPI Keyを含めてリクエストを送信しています。

OAuth認証を使用する場合は、以下のような手順が必要です。

  1. アプリケーションの登録とClient IDとClient Secretの取得
  2. 認可コードの取得
  3. アクセストークンの取得
  4. アクセストークンを使ったAPIへのアクセス

APIの利用制限やレート制限にも注意が必要です。制限に達した場合は、適切なエラーハンドリングとリトライ処理を実装しましょう。

Web APIを使う際は、APIのドキュメントを確認することが重要です。エンドポイントやHTTPメソッド、データ形式、認証方法などを把握し、適切にリクエストを送信しましょう。

requestsを使えば、Web APIとの連携を簡単に実装できます。APIを活用することで、アプリケーションの機能を拡張し、外部サービスとの連携を実現できます。

requestsをマルチスレッド/非同期処理で高速化する

requestsを使ってWeb APIとの通信を行う際、複数のリクエストを順番に処理すると時間がかかってしまうことがあります。そこで、マルチスレッドや非同期処理を導入することで、処理を高速化できます。この章では、concurrent.futuresを使ったマルチスレッド処理、grequestsを使った非同期リクエストの送信について解説します。

requestsとconcurrent.futuresを使った並列処理

concurrent.futuresモジュールを使うと、簡単にマルチスレッド処理を実装できます。以下は、複数のURLに対してGETリクエストを送信する例です。

import concurrent.futures
import requests

urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
]

def fetch(url):
    response = requests.get(url)
    return response.json()

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    futures = [executor.submit(fetch, url) for url in urls]
    results = [future.result() for future in concurrent.futures.as_completed(futures)]

for result in results:
    print(result)

ThreadPoolExecutorを使って、3つのスレッドを並行して実行しています。submit()で各スレッドにタスクを割り当て、as_completed()で完了したタスクの結果を取得しています。

マルチプロセス処理を行う場合は、ProcessPoolExecutorを使用します。

with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
    futures = [executor.submit(fetch, url) for url in urls]
    results = [future.result() for future in concurrent.futures.as_completed(futures)]

grequestsによる非同期リクエストの送信

grequestsは、requestsのラッパーライブラリで、非同期リクエストを簡単に送信できます。

import grequests

urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
]

requests = (grequests.get(url) for url in urls)
responses = grequests.map(requests)

for response in responses:
    print(response.json())

grequests.get()で非同期リクエストを作成し、grequests.map()で複数のリクエストを並行して送信します。レスポンスはresponsesリストに格納されます。

マルチスレッド/非同期処理を導入する際は、以下の点に注意が必要です。

  • I/O bound な処理に適しており、CPU bound な処理には向かない
  • 実装が複雑になり、デバッグが難しくなる場合がある
  • 同期処理が必要な部分では、適切に排他制御を行う

また、大量のリクエストを短時間で送信すると、サーバー側に負荷がかかる可能性があります。リクエストの間隔を調整したり、リトライ処理を実装したりするなど、サーバー側の負荷を考慮した実装が必要です。

マルチスレッド/非同期処理を活用することで、requestsを使ったWeb APIとの通信を高速化できます。処理の特性に応じて適切な手法を選択し、効率的なプログラムを実装しましょう。

requestsでのエラー対策とデバッグ手法

requestsを使ってWeb APIと通信する際、ネットワークエラーやサーバー側のエラーなどが発生することがあります。エラーを適切に処理し、デバッグを行うことが重要です。この章では、RequestExceptionと主なエラーの種類・原因・対処法、デバッグ出力とロギングによるエラー原因の特定、pdbを使ったデバッグについて解説します。

RequestExceptionと主なエラーの種類・原因・対処法

requestsでエラーが発生した場合、RequestExceptionが投げられます。主なエラーの種類と原因は以下の通りです。

  • ConnectionError: ネットワーク接続エラー(サーバーダウン、ネットワーク障害など)
  • Timeout: リクエストがタイムアウトした
  • HTTPError: HTTP 4xx、5xxエラー(リクエストエラー、サーバーエラーなど)
  • TooManyRedirects: リダイレクト回数が上限を超えた

これらのエラーは、try-except文を使ってキャッチし、適切に処理する必要があります。

import requests
from requests.exceptions import RequestException, Timeout, HTTPError

try:
    response = requests.get('https://api.example.com/users')
    response.raise_for_status()
except Timeout:
    print('タイムアウトしました')
except HTTPError as e:
    print(f'HTTPエラーが発生しました: {e}')
except RequestException as e:
    print(f'requestsでエラーが発生しました: {e}')

raise_for_status()を呼び出すことで、ステータスコードが4xx、5xxの場合にHTTPErrorが発生します。

タイムアウトエラーを回避するには、timeoutパラメータでタイムアウト時間を調整します。また、max_retriesパラメータやbackoff_factorパラメータを使ってリトライ処理を実装することもできます。

デバッグ出力とロギングによるエラー原因の特定

エラーの原因を特定するには、デバッグ出力とロギングが有効です。loggingモジュールを使って、リクエストとレスポンスの詳細情報をログに出力しましょう。

import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

response = requests.get('https://api.example.com/users')
logger.debug(f'Request: {response.request.url}')
logger.debug(f'Request Headers: {response.request.headers}')
logger.debug(f'Response Status Code: {response.status_code}')
logger.debug(f'Response Headers: {response.headers}')
logger.debug(f'Response Body: {response.text}')

ログレベルを設定することで、必要な情報だけを出力できます。レスポンスのステータスコード、ヘッダー、ボディを確認することで、エラーの原因を特定しやすくなります。

Timeoutの設定とBackoff処理の実装

タイムアウトエラーを回避するには、timeoutパラメータを使ってタイムアウト時間を設定します。

response = requests.get('https://api.example.com/users', timeout=5)

また、一時的なエラーが発生した場合にリトライ処理を実装することで、エラーを回復できる場合があります。backoffライブラリを使うと、指数関数的バックオフアルゴリズムを簡単に実装できます。

import backoff
import requests

@backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=5)
def fetch_data():
    response = requests.get('https://api.example.com/users')
    response.raise_for_status()
    return response.json()

try:
    data = fetch_data()
    print(data)
except requests.exceptions.RequestException as e:
    print(f'リトライしましたが、エラーが発生しました: {e}')

@backoff.on_exceptionデコレーターを使って、指定した例外が発生した場合にリトライ処理を実行します。max_triesでリトライ回数を指定できます。

requestsを使う際は、エラー処理とデバッグを適切に行うことが重要です。エラーをキャッチし、原因を特定し、適切な対処を行うことで、安定したプログラムを実装できます。ネットワークモニタリングツールやモックを活用することで、さらに効率的にデバッグを行うことができるでしょう。

まとめ:効率的なwebスクレイピングとAPI連携のために

この記事では、Pythonの強力なHTTP通信ライブラリであるrequestsの基本的な使い方から、webスクレイピングやAPI連携への応用まで、幅広く解説してきました。

最初に、requestsの概要と特徴、インストール方法を説明し、シンプルなGETリクエストの例から始まりました。次に、webスクレイピングに必要なHTMLの取得方法やクッキー、セッション、認証の扱い方を学びました。さらに、Beautiful SoupやPandasと組み合わせたスクレイピングテクニックも紹介しました。

Web APIとの連携では、GET/POST/PUT/DELETEリクエストの送信方法、JSONデータの取得とデータ構造の理解、認証付きAPIの使用法などを解説しました。また、マルチスレッドや非同期処理を用いたリクエストの高速化手法も学びました。

最後に、requestsを使う上で避けては通れないエラー処理とデバッグ手法について説明しました。例外処理の方法、ロギングによるデバッグ、バックオフ処理の実装など、安定したプログラムを開発するためのポイントを押さえました。

この記事で紹介した内容を活用することで、みなさんもPythonでのスクレイピングやAPI連携の実装に挑戦してみてください。requestsは、シンプルで扱いやすい反面、非常に柔軟性と拡張性に富んだライブラリです。ここで学んだテクニックを応用し、オリジナルのプログラムを開発してみましょう。

Pythonでのデータ収集や解析は、近年ますます重要になっています。スクレイピングやAPIを活用することで、ビジネスや研究に役立つ知見を得ることができるでしょう。今回の記事が、みなさんのPythonライフに新しい可能性をもたらすきっかけになれば幸いです。

最後までお読みいただき、ありがとうございました。コメント欄では、記事の感想やご質問をお待ちしております。Pythonでのスクレイピングや、requestsの使い方について、ぜひ活発に意見交換しましょう!