【python】スクレイピングを高速化する並行処理する方法 (ThreadPoolExecutor)

pythonは少ないコードで実装でき,可読性にすぐれ,最もよく使われているプログラミング言語となっています

しかし,pythonはインタプリタ型言語で処理がほかの言語と比べて遅いというデメリットがあります.

そこでpythonの処理を速くするために,並行化と並列化があり,Webからデータを収集するスクレイピングでは,並行化を使用することで劇的にデータ収集が高速になります.

本記事は並行化でスクレイピングを高速化する方法を解説していきます

目次

concurrent.futures.ThreadPoolExecutorで並行化

このライブラリで並行化します

手順は並行処理したいfor文以下で実行されている箇所を関数化します

次にThreadPool内でその関数を実行します

並行化したい処理

関数にするまでの過程も一緒に書いていきます

まずは関数の前の段階です

secs = [5, 4, 3, 2, 1]

for sec in secs:
    print(f'{sec}秒待機中...')
    time.sleep(sec)
    print(f'{sec}秒待機終了')

#5秒待機中...
#5秒待機終了
#4秒待機中...
#4秒待機終了
#3秒待機中...
#3秒待機終了
#2秒待機中...
#2秒待機終了
#1秒待機中...
#1秒待機終了

これを関数化しましょう

引数にforで回ってくる要素であるsecを指定します

戻り値には{sec}秒待機終了という文字列を受け取ります

def wait_time(sec):
    print(f'{sec}秒待機中...')
    time.sleep(sec)
    return f'{sec}秒待機終了'

このwait_timeという関数をmapを使って実行します

すこし直感的でないという方がいるかもしれませんので少し解説します

secs = [5, 4, 3, 2, 1]

results = map(wait_time, secs)
for result in results:
    print(result)

mapの第一引数に実行したい関数

第二引数にリストなどのiteratorを指定します

これでsecsでfor文を回して,その要素を引数としてwait_timeが受け取り,戻り値をresultsに格納してくれま

これで関数の準備は終了です

並行化

上記の関数を並行処理します

import concurrent.futures

with concurrent.futures.ThreadPoolExecutor() as executor:
    secs = [5, 4, 3, 2, 1]
    results = executor.map(wait_time, secs)

withブロックの中に処理を記載します

これで並行処理ができまし

時間を計測すると,もともとの構文では15.04秒でした

並行化すると5.01秒になり,最大秒数である5秒に収まりましたね

まとめ:並行化のコード

最後に並行化したコードをすべてを貼っておきます

if name == ‘main‘:以下に処理を書かないと動かないことがあるので気を付けてください

ではお疲れ様でした

import concurrent.futures
import time

start = time.perf_counter()

def wait_time(sec):
    print(f'{sec}秒待機中...')
    time.sleep(sec)
    return f'{sec}秒待機終了'

if __name__ == '__main__':
    with concurrent.futures.ThreadPoolExecutor() as executor:
        secs = [5, 4, 3, 2, 1]
        results = executor.map(wait_time, secs)

    for result in results:
        print(result)

    finish = time.perf_counter()
    print(f'{round(finish-start, 2)}秒で終了')
シェアしてくださると嬉しいです!
  • URLをコピーしました!

コメント

コメントする

目次