そもそも「urllib3」と「httpx」って何?
Pythonにwebサイトからデータを取ってこさせるためのパシリの道具や。
プログラムに自動で
「あのサイトのデータを集めてきて!」
とか
「この画像ダウンロードしてきて!」
って命令したいときがあるやろ?
その時に、プログラムの代わりにインターネットの世界へお使いに行ってくれるのが、こいつらなんや。
本題!「urllib3」と「httpx」の違い
urllib3
-
キャラ
- 昔ながらの、頑固で超タフなベテラン職人
-
特徴
- めちゃくちゃ昔からあって、絶対に倒れない安定感がある。ただ、職人気質すぎて、「呪文(コード)が長くて書くのがめんどくさい」という弱点がある。
-
ぶっちゃけ話
- 最近のエンジニアは、urllib3 を直接自分で使うことはあんまりない。でも、他の有名な道具(requestsっていう超人気ライブラリなど)の「裏方(エンジン)」としてめちゃくちゃ働いてる。縁の下の力持ちや。
httpx
-
キャラ
- 令和生まれの、最先端トリプルスリーの若手エース
-
特徴
- ベテラン(urllib3)の良いところをマネしつつ、「現代風にめちゃくちゃ書きやすくした」道具
- さらに、最大の武器として「非同期処理」ができる
-
非同期処理って何?
- 普通のパシリは、1つのサイトに行ってデータを持って帰ってくるまで、次のサイトに行けへん(待ち時間が発生する)。でも httpx は、「10箇所のサイトに同時にダッシュして、一気にデータを取ってくる」みたいなワザが使えるんや。めちゃくちゃ足が速い。
urllib3のサンプルコード
GET(データをちょうだい!)の基本コード
import urllib3
# ① パシリの親分(プールマネージャー)を呼び出す
# これを作っておくと、通信の回線を上手いこと使い回してくれて効率がええんや
http = urllib3.PoolManager()
# ② 「GET」でデータを取ってきて!と命令する
# (httpbin.org は、通信のテストによく使われる便利な実験用サイトやで)
url = "https://httpbin.org/get"
response = http.request("GET", url)
# ③ 結果を確認する
print(f"ステータスコード: {response.status}") # 「200」って出たら大成功!
# 帰ってきたデータ(response.data)は、そのままやとコンピュータ専用の生データ(バイナリ)や。
# やから `.decode('utf-8')` を使って、人間に読める文字(テキスト)に翻訳してあげるんや。
print("--- 届いたデータの中身 ---")
print(response.data.decode("utf-8"))
POST(データを送りつける!)の基本コード
import json
import urllib3
http = urllib3.PoolManager()
# ① 送りたい荷物(データ)を準備する
# Pythonの「辞書型(連想配列)」で書くのが基本やな
my_delivery = {"name": "たこ焼きおじさん", "order": "特製ソース10個", "count": 1}
# ② 荷物を「ネットの箱(JSON)」に詰めて、荷札(エンコード)を貼る
# urllib3は職人気質やから、文字のままだと「これじゃ運べん!」って怒る。
# json.dumps で世界共通のJSON文字列にして、さらに .encode('utf-8') で電気信号(バイト型)に変えるんや
encoded_body = json.dumps(my_delivery).encode("utf-8")
# ③ 「POST」で荷物を送りつける!
url = "https://httpbin.org/post"
response = http.request(
"POST",
url,
body=encoded_body, # 👈 ここにさっき作った荷物を乗せる
headers={"Content-Type": "application/json"}, # 👈 「中身はJSONやで」という看板
)
# ④ 相手からの「受け取ったでー」というお返事を確認する
print(f"ステータスコード: {response.status}") # 200 とか 201 なら無事届いてる!
print("--- 相手からの返事の中身 ---")
print(response.data.decode("utf-8"))
httpxのサンプルコード
urllib3のサンプルコードを見てると、
「うわ、POSTするときに json.dumps して .encode して…って、なんかやること多くてめんどくさいな...」
「GETの時は最初に準備(PoolManager)して…」とか「届いた生データを翻訳(decode)せなあかんのか…」
って思わんかった?
令和の最新道具 httpx を使うとこのめんどくさい変換を道具側が勝手にやってくれるんよ。
GET(データをちょうだい!)の基本コード
# httpxなら、辞書のまま「json=」に放り込むだけで勝手に変換して送ってくれる!
response = client.post("https://httpbin.org/post", json=my_delivery)
POST(データを送りつける!)の基本コード
import httpx
# ① いきなり「GET」で指定のURLに突撃!
url = "https://httpbin.org/get"
response = httpx.get(url)
# ② 結果を確認する
print(f"ステータスコード: {response.status_code}") # urllib3は .status だったけど、こっちは .status_code やね
# ③ 届いたデータ(中身)を見る
# 💡 ここが超ラク! .text って書くだけで、勝手に人間に読める文字に翻訳してくれてる!
print("--- 届いたテキストデータ ---")
print(response.text)
# 💡 もし相手が「JSON(データ箱)」を返してくれてるって分かってたら、
# `.json()` って書くだけで、一瞬でPythonの辞書型に一発変換してくれる!
# print(response.json())
Lambdaで使うときの注意点
Lambdaの部屋は「最低限の家具しかないワンルーム」
AWS Lambdaっていうのは、「プログラムが動くときだけ一瞬で立ち上がる、超ウルトラ省エネな部屋」みたいなもんや。
AWS側としては、部屋をできるだけ軽くして爆速で起動させたいから、余計な道具(ライブラリ)は一切置きたくないんよ。
- urllib3:AWSを操作する公式の道具(boto3)が裏で使うから、最初から部屋に備え付けられてる。
- httpx: 令和の最新の道具やから、AWSの初期状態の部屋には置いてへん。
だから、自分で import httpx って書いたコードをそのままLambdaに貼り付けて実行すると、「そんな道具、この部屋にはありません!」ってエラー(ModuleNotFoundError)でブチギレられるんや。
じゃあ、どうやって httpx を部屋に持ち込むの?
持ち込む方法は、主に2つある。
① Lambda Layerを使う【おすすめ】
httpx をあらかじめzipファイルに固めて、AWSに「追加の道具箱(レイヤー)」として登録しておく方法や。
これをやっとくと、Amazonのクローゼットに自分の道具箱を預けておくようなもんやから、他のLambdaを作ったときにも「あ、あの httpx の道具箱、この部屋にも持ってきて!」って使い回しができる。部屋のコード自体もスッキリ保てるから、エンジニアはみんなこの方法が大好きや。
② コードと一緒に全部まとめてzipで送る【同梱スタイル】
自分のプログラム(lambda_function.py)と同じフォルダの中に、パソコンで httpx を直接インストールしてまう方法や。
pip install -t . httpx (このフォルダの中にhttpxをダウンロードせよ!の呪文)
これで、自分のコードと httpx の中身が1つのフォルダにゴチャッと入るから、それを全部丸ごとzipで固めてLambdaにドカンとアップロードする。
わざわざ「レイヤー」っていう別枠の道具箱を作らんでええから、1回限りの使い捨てプログラムとかならこっちの方が手軽やったりするな。
urllib3 と httpx の違い超・爆速まとめ
urllib3
Lambdaに最初からおる urllib3 はな、言うたら 『実家の冷蔵庫に常備されてる麦茶』 や!
オシャレさも最新機能(非同期)もゼロやけど、手ぶらで実家帰ってもそこにあるだけでなんか安心するやろ?
httpx
対して httpx は 『スタバの新作フラペチーノ』 や!
わざわざ店まで買いに行かな(インストールせな)手に入らんし、呪文(Async)唱えなあかんけど、手に入れたら美味いし一気に今風でカッコよくなる(コードが綺麗)!
これから新しくプログラム書くなら、ちょっと背伸びしてでも 『スタバ(httpx)』 に並ぶのが大正解やで!!