PythonとSeleniumをheadlessで動かしても速くならない理由

seleniumによるHTML解析を10倍速くした方法 Pythonの使い方

seleniumをheadlessモードで動かすと速くなると言われていますが、実際に測定したことがなかったので測定してみました。

結果は、ヘッドレスモードで速くなるものの、現実的なWEBスクレイピングの運用では、ヘッドレスモードの恩恵を受け取れません。サーバや通信経路等による速度への影響が大きいためです。

seleniumをheadlessモードで、速度測定した方法

WEBサイトをget()してから完了するまでの時間を測定しました。

計測対象としたサイトは、以下のものです。

  • ローカルサーバある、外部にアクセスをしないhtml
  • ローカルサーバにコピーした、コーポレートサイト(WordPress)
  • インターネット上のサイト3つ

これらのサイトをヘッドレスモードでないのとヘッドレスモードで、測定しています。

Pythonの速度を測定したソースコード

全ての測定したソースを書くと長くなるので、実践的な測定を行ったものだけです。

簡単に説明すると、ヘッドレスでないドライバーと、ヘッドレスのドライバーを交互に動かして、get()前後の時間を測定します。

交互にしているのは、time.perf_counter()で測定しているため、PCの状況に影響を受けやすく事による、測定環境が互いに異なることを回避するためです。また、最初のget()は測定していませんが、ブラウザの起動時間の影響をなくすためです。

測定は、get()からタグが全て読み終わるまでの時間です。全て30回測定しています。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

url_0 = "https://pc.watch.impress.co.jp/"
url_1 = "https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A3%E3%82%AD"
url_2 = "https://moneykit.net/"

driver_a = webdriver.Chrome()
wait_a = WebDriverWait(driver_a, 10)
driver_a.get(url)
time.sleep(3)

options = Options()
options.add_argument('--headless')
driver_b = webdriver.Chrome(chrome_options=options)
wait_b = WebDriverWait(driver_a, 10)
driver_b.get(url)
time.sleep(3)

urls = [url_2, url_0, url_1]

dt_a = []
dt_b = []
for count in range(33):
    url = urls[count % 3]

    crt_counter = time.perf_counter()
    driver_a.get(url)
    wait_a.until(EC.visibility_of_all_elements_located)
    if count >= 3:
        dt_a.append(time.perf_counter()-crt_counter)

    crt_counter = time.perf_counter()
    driver_b.get(url)
    wait_b.until(EC.visibility_of_all_elements_located)
    if count >= 3:
        dt_b.append(time.perf_counter() - crt_counter)

seleniiumをheadlessモードによる速度効果の測定結果

ヘッドレスモードでないのとヘッドレスモードの時の測定結果です。それぞれ、30回計測しています。

測定対象としたのは、get()コールから全てのタグが読み終わるまでです。

ローカルサーバにある外部にアクセスをしないhtmlの測定結果

ローカルサーバに置いた、HTMLファイルを取得する時間です。HTMLは、一行”google”と書かれているだけです。外部へファイルを求める記述は一切ありません。

項目 平均時間(sec) 標準偏差(sec)
非ヘッドレス 0.0125 0.0007
ヘッドレス 0.0094 0.0007
変化率(%) 75.2

ヘッドレスモードにするだけで、25%弱も速くなりました。素晴らしいです。アルゴリズムに悩むことなく、ほんの2行を加えるだけで、速くなるのです。

ローカルサーバにコピーした、コーポレートサイト(WordPress)

今度は、ローカルサーバのWordPressをseleniumでget()してみます。外部のjQueryを使っています。

項目 平均時間(sec) 標準偏差(sec)
非ヘッドレス 0.5392 0.0693
ヘッドレス 0.538 0.0119
変化率(%) 99.8

平均時間だけをみると、ヘッドレスモードの設定が速度に影響しないとも捉えられますが、たまたま同じ数値が出た可能性もあります。その証拠に、非ヘッドレスの標準偏差が高く、平均時間の1割強にも達しています。

そこで再測定です。300回測定しました。

項目 平均時間(sec) 標準偏差(sec)
非ヘッドレス 0.5482 0.0880
ヘッドレス 0.5510 0.0488
変化率(%) 100.5

しかし、先の結果と同様に、ヘッドレスモードは、速度への影響がありませんでした。

インターネット上のサイト3つの測定結果

ローカルサーバでは、上記の通りヘッドレスモードは全く速度への貢献を果たしてくれませんでしたが、今度は実際のスクレイピングのようにWEBサイトを取りに行って測定です。3サイトをそれぞれ10回ずつ測定しています。

項目 平均時間(sec) 標準偏差(sec)
非ヘッドレス 0.9482 0.3443
ヘッドレス 1.0886 0.5339
変化率(%) 114.8

ヘッドレスモードの平均時間の方が増えてしまいました。というよりも、標準偏差が平均時間の5割にも達しているので、平均時間の比較に価値はなさそうです。

seleniumのヘッドレスモードが速度に与える影響

最初の結論の通り、ヘッドレスモードにすれば、get()からHTML分析前までの時間は、速くなります。ローカル環境で速くなったのがその証拠です。

しかし、インターネット上のデータを拾いに行くスクレイピングが目的の場合、他の要素が速度へ影響して、測定する価値はありません。ブラウザにスクレイピングしている様子が見えようが見えまいが、速度にまったく影響がないのです。

コメント

タイトルとURLをコピーしました