こんにちは。TATです。
今日はPythonのコード解説記事です。
テーマは「Seleniumでfinvizのヒートマップのスクショを保存する」です。
こちらの記事で使ったスクショをSeleniumで自動取得して保存する方法を解説します。
【Pythonでデータ分析】株クラで目にする「おはぎゃー」のプロセスを自動化してみた!
こんなスクショを取得することを目指します。
(ちなみにこの記事を書いたのは過去記事とは別日なのでスクショ内容は異なります。)
通常であれば、finvizのページにアクセスして手動でスクショを保存することになりますが、今回はここを自動化します。
Seleniumを使うと、ウェブブラウザ(ページ遷移やボタンクリックなど)の動作を自動化することができます。
データ収集などにおいてもとても役立つので、覚えておくとかなり重宝します。
目次
【Pythonコード解説】Seleniumでfinvizのヒートマップのスクショを保存する
Seleniumの準備
まずはSeleniumの準備です。
Seleniumを利用するにはライブラリーのインストールと、WebDriverの準備が必要になります。
使用するブラウザについては、よほどの理由がない限りはChromeで良いかと思います。
こちらのページからSeleniumに利用するWebDriverをダウンロードすることができます。
→ ChromeDriver - WebDriver for Chrome
バージョンはご自身が利用しているChromeのバージョンに合わせておけば大丈夫です。
現在使用しているChromeのバージョンは、Chromeを開いていただいてURLに「chrome://version/」を入力していただくと確認できます。
必要なChromeのWebDriverをダウンロードしたら、適当な場所に保存してください。
WebDriverを使用する際にはPathを指定できるので、どこにおいても問題はありません。
一番楽なのは、プログラムを走らせるディレクトリーにおいてしまうことです。(Pathの指定なしでアクセスできます)
PythonでSeleniumを利用する方法!セットアップの流れを徹底解説します!
続きを見る
finvizのサイト構造を確認する
次に今回のターゲットであるfinvizのサイトを確認します。
こちらへアクセスすると、株式投資家にはおなじみのアメリカ株の個別銘柄のヒートマップを確認することができます。
ここがほぼ全て赤くなっていたら(つまり全部下落)、株クラおなじみの「おはぎゃー」ツイートが出てきます。
今回取得したい画像はヒートマップの部分だけになります。
普通にスクショを撮ると余計な部分も入ってくるので少し工夫が必要です。
大変ありがたいことに、Seleniumにはサイトの一部を指定してスクショを保存することができます。
感謝ですね。
サイトの構造を見ると、対象のヒートマップにはcanvasタグが当てられ、なおかつクラス名はchartとなっています。わかりやすいですね。
(ちなみにこちらのスクショはSeleniumで動かしている際に撮ったものです。この場合「Chromeは自動テストソフトウェアによって制御されています」と表記されます。)
よって、ここのタグ部分を指定してスクショを撮ることができればOKです。
さらにHTMLを見ると画像のサイズもきちんと指定されていることがわかります。
ゆえに、スクショを撮る際には画面サイズを指定した上で、このcanvasタグを取得すると画面が切れることなくきれいにヒートマップ全体のスクショを保存できることがわかります。
Seleniumでスクショを保存する
下準備が終わったので、早速プログラムを書いていきます。
ここでやるべき流れをプログラム的に分解するとこんな感じになります。
ちょっと細かいです。
- SeleniumでChromeを起動する
- finvizに遷移する
- 画面サイズを設定する
- canvasタグを指定する
- スクショを撮る
- スクショを保存する
順番に見ていきましょう。
1. SeleniumでChromeを起動する
まずはSeleniumを使ってChromeを起動します。
from selenium import webdriver # SeleniumでGoogle Chromeを起動 driver = webdriver.Chrome() #同ディレクトリにWebDriverがある場合 driver = webdriver.Chrome(executable_path="xxx") #別ディレクトリにWebDriverがある場合
上記の通り。
seleniumからwebdriverをimportして、Chromeを起動します。
プログラムとWebDriverが同じディレクトリにある場合はexecutable_pathという引数は不要です。
異なる場合は適切なPathを指定してあげましょう。
これでChromeが立ち上がります。
まだどこの画面にも遷移していないので画面は真っ白です。
Seleniumで起動した際には、「Chromeは自動テストソフトウェアによって制御されています」と表示されるようになります。
起動したwebdriverはdriverという変数に引き渡されます。
よって、今後Chromeを動かす際には、このdriverという変数をいじっていくことになります。
2. finvizに遷移する
Chromeが無事に起動されたので、finvizのページに遷移していきます。
遷移するのは簡単です。
url = "https://finviz.com/map.ashx?t=sec" driver.get(url)
urlを指定してget関数に引き渡せば完了です。
これで任意のページへアクセスすることができます。
無事に目的のページへアクセスできました。
3. 画面サイズを設定する
次に画面サイズを指定します。
ここをいい感じに設定しておかないとスクショが途中で見切れてしまったりします。
今回はHTMLを確認した時に表示されていた幅1576, 高さ874を使います。
これはある程度の大きさがあればいくつでも問題ないです。
小さすぎると画面が見切れてしまうのでそこだけ注意しましょう。
使用されるPCによって解像度は異なるのでここの数値も変わってくると思います。
Seleniumで画面サイズを設定するのは非常に簡単です。
# 画面サイズの設定 driver.set_window_size(1576, 874)
これだけです。
実行すると起動中の画面サイズが変わるはずです。
4. canvasタグを指定する
次にスクショの対象となるヒートマップを抜き出します。
SeleniumにはHTMLから特定部分を抽出するための機能があります。
今回はclassで指定して抜き出してみることにします。
対象となるヒートマップはcanvasタグで、chartというクラス名がついていました。
これを利用して抽出します。
heatmap = driver.find_element_by_class_name("chart")
これだけです。
ちなみに同じクラス名が複数存在している場合には1つ目のものが取得されます。
こういった場合には、find_elements_by_class_name(elementがelementsになるだけ)を使うと、リスト形式で取得できるので、その後に該当箇所を指定すればOKです。
他にはidで指定したり、cssから特定するなどといった方法が可能です。
5. スクショを撮る
必要な箇所が抽出できたのでスクショを撮ります。
スクショを撮るのも1行で完了します。
bf = heatmap.screenshot_as_png
screenshot_as_pngを使えば、対象の画像を取得できます。
これはバイナリーデータになっているので、そのまま見ると意味不明な感じになっています。
このままだと謎ですが、きちんとフォーマットを指定して保存してあげれば画像ファイルになります。
6. スクショを保存する
それでは取得したスクショを画像ファイルとして保存します。
これも数行で完成です。
with open("screenshot.png", "wb") as f: f.write(bf)
ここでは、取得したスクショデータをscreenshot.pngというファイル名で保存しています。
wbはファイルを開くモードを指して、バイナリー(binaryのb)で書く(writeのw) という意味になります。
バイナリー書き込みモードです。
開いたファイルをfとして、write関数でバイナリーデータを書き込めば終了です。
withを使うと、プログラムが終わったら自動でファイルを閉じてくれるので便利です。
これで画像ファイルとして保存ができました。
取得した画像は、こんな感じできれいに保存されていることがわかります。
Jupyter上で画像を表示するにはIpythonの中にあるimageを使います。
コード全体を確認する
ここまで細切れでコードを紹介してきたので、ここで改めてまとめておきます。
なるべくコメントつけました。
from selenium import webdriver from IPython.display import Image # SeleniumでGoogle Chromeを起動 driver = webdriver.Chrome(executable_path="xxx") #別ディレクトリにWebDriverがある場合はexecutable_pathで指定する # finvizのページへ遷移 url = "https://finviz.com/map.ashx?t=sec" driver.get(url) # 画面サイズの設定 driver.set_window_size(1576, 874) # ヒートマップの抽出 heatmap = driver.find_element_by_class_name("chart") # スクショをバイナリーデータで取得 bf = heatmap.screenshot_as_png # 画像データとして保存する with open("screenshot.png", "wb") as f: f.write(bf)
全体としてみてもかなり短いコードにまとまりますね。
これだけ短いコードでスクショの取得までできてしまうのが、Pythonの素晴らしさです。
(おまけ)ヘッドレスモードでブラウザを非表示にする
最後におまけです。
このプログラムを毎日のように走らせるとなると、いちいちブラウザが立ち上がってくるのはうざったくなることがありますw
こういう場合にはブラウザを立ち上げずにプログラムを実行することが可能です。
それがヘッドレスモードです。
無論、ヘッドレスモードでもスクショの保存は可能です。
この場合はOptionとしてヘッドレスを指定すればOKです。
from selenium import webdriver from selenium.webdriver.chrome.options import Options # ヘッドレスモードを指定する options = Options() options.add_argument('--headless') # SeleniumでGoogle Chromeを起動 driver = webdriver.Chrome(executable_path="xxx", chrome_options=options) #別ディレクトリにWebDriverがある場合はexecutable_pathで指定する
上記のコードを実行すると、ブラウザを立ち上げることなくWebDriverを動かすことができます。
使いどころとしては、最初はブラウザでの動きを見ながら動作確認と並行してプログラムを開発して、問題がなければヘッドレスモードに移行するパターンが多いです。
今回のプログラムはとても短いためすぐに終わるので問題ないですが、数時間も走り続けるようなプログラムの場合は勝手にブラウザが動いていると結構邪魔です。
特にプログラムを走らせながら別の作業をしたいという場合には、ヘッドレスモードにしておくと快適になります。
もしご興味があればお試しください。
まとめ
いかがでしたでしょうか。
今回は「Seleniumでfinvizのヒートマップのスクショを保存する」というテーマでSeleniumを使ってスクショを撮る方法についてPythonコード付きで解説しました。
Seleniumを使うと、普段僕たちが使っているウェブ上での操作を自動化できるので、データの収集とかサイトの動作テストなんかによく使われます。
汎用性も高いので、知っておくと結構使える場面が出てくるのでオススメです。
是非ともお試しください。
ここまで読んでくださってありがとうございました。
【Pythonでデータ分析】株クラで目にする「おはぎゃー」のプロセスを自動化してみた!
続きを見る