PythonでSeleniumを使うと、Google Chromeを自動操作することが可能です。実際にChromeが画面上に立ち上がる動作をしますが、決まった操作であればあえてPC画面に表示させる必要はありません。ここではSeleniumでChromeを使う時に画面に何も表示させないヘッドレス起動の方法を紹介します。
こんにちは。wat(@watlablog)です。
Selenium関係もかなり慣れて来ましたが、ここではスクレイピング時にブラウザを画面に表示させないヘッドレス起動の方法を紹介します!
Chromeをヘッドレスで起動させるメリット
①実行中に干渉できないので同じPCで同時作業ができる
SeleniumでGoogle Chromeを操作する場合でも、ユーザはブラウザに干渉することが出来てしまいます。
例えばWebサイトを攻撃しないようにプログラム上で待機させている時に、画面をスクロールさせてみたり、リンクをクリックしてみたりといった行動が可能です。
故意でなくても、マウス操作の最中に意図せずそのような操作をしてしまうこともあるでしょう。するとプログラム開発者が予期していないアクションによりエラー終了してしまう可能性もあります。
ヘッドレスモードとしてChromeを立ち上げれば、ユーザはそのような操作をすることが出来なくなるため、外乱の少ない処理が可能になります。
②実行速度が速くなる?→検証しました。
Chromeをヘッドレスモードで起動させることで、PCがブラウザを表示しなくなるため、その分処理速度が速くなると言われています。
プログラムはできるだけ速く動作させた方が良いのは明白ですので、このメリットは非常に嬉しいですね。
本記事では実際にWebスクレイピングを行うプログラムを使って、ヘッドレスモードの有無によるプログラム処理時間を計測してみましたが、やはり言われていることは正しかったようです。
記事の最後の方にグラフを載せましたが、例題のプログラムではヘッドレスモードにすることで約6.7%ほど処理時間が速くなりました。
Python/SeleniumでChromeをヘッドレス起動させるコード
事前準備
このページでは、Pythonの外部パッケージであるseleniumとchromedriver-binaryを使います。これらのインストールからプログラム例までの説明は「PythonでGoogle検索タイトルとURL一覧を抽出してみた」の「2.1.事前準備」に記載しましたので、予備知識が不足していると感じた場合は是非こちらの記事も参照してみて下さい。
ヘッドレス化はオプションで指定する
Chromeのブラウザをプログラム実行中に画面に表示させないヘッドレスモードで起動する方法は、「SeleniumのChromeをシークレットモードで起動する」で指定した時と同じOptionsを使います。
そのため、import文にもOptionsが必要になります。
ヘッドレスモードのオプション引数は'--headless'です。今回はヘッドレスモードだけしか書いていませんが、シークレットモードとの併用も可能です。オプションを併用する場合はadd_argumentを複数行にわたって書いて下さい。
以下にimportからwebdriverの準備までのコードを示します。
1 2 3 4 5 6 7 |
from selenium import webdriver # Webブラウザを自動操作する(python -m pip install selenium) import chromedriver_binary # パスを通すためのコード from selenium.webdriver.chrome.options import Options # オプションを使うために必要 option = Options() # オプションを用意 option.add_argument('--headless') # ヘッドレスモードの設定を付与 driver = webdriver.Chrome(options=option) # Chromeを準備(optionでヘッドレスモードにしている) |
ヘッドレスモードでWebスクレイピングをする方法
それでは実際にヘッドレスモードでWebスクレイピングするコードを使ってみましょう。そして、プログラム処理時間の計測を行い、ヘッドレスモードを使った時と使わない時でどの程度差が出るのかを確認してみます。
以下が全コードです。処理時間計測の方法は「Pythonプログラムの処理にかかる時間を計測する方法」で紹介した内容をそのまま使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import time # スリープを使うために必要 from selenium import webdriver # Webブラウザを自動操作する(python -m pip install selenium) import chromedriver_binary # パスを通すためのコード from selenium.webdriver.chrome.options import Options # オプションを使うために必要 t0 = time.time() # 計測用初期時間[s] option = Options() # オプションを用意 option.add_argument('--headless') # ヘッドレスモードの設定を付与 driver = webdriver.Chrome(options=option) # Chromeを準備(optionでヘッドレスモードにしている) # サンプルのHTMLを開く driver.get('https://www.google.com/') # Googleを開く search = driver.find_element_by_name('q') # HTML内で検索ボックス(name='q')を指定する search.send_keys('WATLABブログ') # 検索ワードを送信する search.submit() # 検索を実行 time.sleep(3) # 3秒間待機 def ranking(driver): i = 1 # ループ番号、ページ番号を定義 i_max = 2 # 最大何ページまで分析するかを定義 title_list = [] # タイトルを格納する空リストを用意 link_list = [] # URLを格納する空リストを用意 # 現在のページが指定した最大分析ページを超えるまでループする while i <= i_max: # タイトルとリンクはclass="r"に入っている class_group = driver.find_elements_by_class_name('r') # タイトルとリンクを抽出しリストに追加するforループ for elem in class_group: title_list.append(elem.find_element_by_class_name('LC20lb').text) #タイトル(class="LC20lb") link_list.append(elem.find_element_by_tag_name('a').get_attribute('href')) #リンク(aタグのhref属性) # 「次へ」は1つしかないが、あえてelementsで複数検索。空のリストであれば最終ページの意味になる。 if driver.find_elements_by_id('pnnext') == []: i = i_max + 1 else: # 次ページのURLはid="pnnext"のhref属性 next_page = driver.find_element_by_id('pnnext').get_attribute('href') driver.get(next_page) # 次ページへ遷移する i = i + 1 # iを更新 time.sleep(3) # 3秒間待機 return title_list, link_list # タイトルとリンクのリストを戻り値に指定 # ranking関数を実行してタイトルとURLリストを取得する title, link = ranking(driver) # タイトルリストをテキストに保存 with open('title.txt', mode='w', encoding='utf-8') as f: f.write("\n".join(title)) # URLリストをテキストに保存 with open('link.txt', mode='w', encoding='utf-8') as f: f.write("\n".join(link)) driver.quit() # ブラウザを閉じる t1 = time.time() # プログラム終了時の時間[s] elapsed_time = t1 - t0 # 経過時間[s] print(elapsed_time) # 経過時間の表示 |
【実験結果】ヘッドレスモードで起動すると少し処理速度が速くなる
以下の図は上記コードでヘッドレスモードで起動した場合と、ヘッドレスを使わない通常モードで起動した場合の処理時間を比較したグラフです。
ヘッドレスモードは通常モードよりも約6.7%処理時間が速いという計測結果が得られました。
今回は10回の測定結果の平均を示していますが、この時点で標準偏差は共に0.4sくらいだったので、十分有意差と言って良いのではないかと思います。
まとめ
本ページではSeleniumでGoogle Chromeをヘッドレスモードとして立ち上げるメリットとオプションで指定する方法を説明しました。
Webスクレイピングをするサンプルコードを使ってヘッドレスモードを使うと、使わない時と比べて2sほど(約6.7%)処理時間が改善するという結果を得ました。
外乱の影響の少ない、そして処理時間が速くなる(必ずしも速くなるとは言い切れていないので、実際に計測して確認する必要はあります。)ヘッドレスモードを是非使ってみて下さい。
様々なオプションを使いこなすと快適に、そして効率よくスクレイピングをすることが出来そうですね!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!