【マルチスレッド化】Webスクレイピングを高速化する方法

こんにちは、のっくんです。

今日はマルチスレッディングを使ってWebスクレイピングを高速化する方法をご紹介します。

Webスクレイピングでは、

  1. requestsでURLにアクセスしHTMLをダウンロード
  2. タグの情報をBeatifulSoupでスクレイピングする

のが一般的です。

しかし、接続先URLが多数あると1番でかなり時間がかかります。

ネットワーク遅延等で処理に時間がかかるからです。

そういう場合にはマルチスレッド化することで高速化できます。

今日はその高速化した例をコードと共にご紹介します。

スポンサーリンク

Wikipediaの例

必要なパッケージのインポート

スクレイピングに必要なrequestsとマルチスレッドに必要なTreadPoolExecuterをインポートします。

partialは、引数を固定したいときに使います。今回は、ヘッダー情報を引数として固定したいので使用します。

URLのリストを作成する

スクレイピングに使用するURLの一覧をリスト化します。

URLはWikipediaの機械学習に関するページにします。

シングルスレッドで実行する

まずはシングルスレッドで実行した場合にどの程度時間がかかるか計測してみます。

実行結果は以下の通り。

コードの実行時間は「Wall time」です。1.15秒かかりました。

マルチスレッドで実行する

次はマルチスレッドで実行してみます。

実行結果は以下の通り。

0.39秒で実行できました。シングルスレッドに比べて速くなりました。

海外サイトの例

マルチスレッドだと高速化できることは分かりましたが、上記の例だと普通にアクセスしても1秒程度で情報を取得できてしまうのであまりマルチスレッディングのありがたみを感じません。

そこで、普通にアクセスするとかなり時間がかかる海外のサイトで速度を比較してみましょう。

以下のURLは、プレミアリーグの移籍金が掲載されているページです。

アクセスしてみると分かりますが表示するまでにかなり時間がかかります。

さらに、その年ごとにURLが異なるので13年分の移籍金情報を取得するには13回アクセスする必要があります。

かなり重いページですが、今回のマルチスレッディングの効果を確かめるには有効です。

シングルスレッド

このサイトですがヘッダーにUser-Agentがないとアクセスできないようになっているので、User-Agentを指定してアクセスします。

requests.getでサイトにアクセスする際に、ヘッダー情報をキーワード引数として指定する必要があります。

なんと2分48秒もかかっています。気が遠くなるような遅さですね。

マルチスレッド

今回のようにmap関数に関数を渡すときにキーワード引数を固定化するには、partialを使うと便利です。
なんと5秒で実行できました。これぞマルチスレッドの威力!

おわり。

参考

https://medium.com/towards-artificial-intelligence/the-why-when-and-how-of-using-python-multi-threading-and-multi-processing-afd1b8a8ecca