今回は、今更ながら「Selenium」でChromeを触ってみたら、今までやっていたIE操作より便利すぎて驚いたというお話です。
[前置き]
ここから先登場する「IE操作」とはmshtmlを使用してInternetExplorerを操作する処理。
「Chrome操作」はSelenium WebDriverを用いてChromeブラウザを操作する処理を指します。
「Selenium」については元々存在は知っていたのですが、
わざわざWebDriver落として来て環境整えなくても、あのマイクロソフトさんが「mshtml」なんてdllを用意してくれてるんだしIEで良くない?
と、ずっと思っていたので今まで全く触って来なかったんです。
ついでにもう一つ理由があって、例えばサイト上のテキストボックスなんかに値を入れる場合。
IE操作では
ie.Document.getElementById("hoge").value = "hogehoge"
ってな感じでvalueに対して直接値を突っ込みますが、
Seleniumでは
Dim element As WebElement = ChromeDriver.findElement(By.id("hoge")) element.clear() element.SendKeys(value)
という風に「SendKeys」を使います。
まぁここでVBを暫く使っていた私は思う訳です。
「値の貼り付け方法がSendKeysって(笑)」と。
これじゃあ安定しそうにないしこれは使えないなーと思い、結局触らないまま今に至ったという感じです。
まぁ実は名前が同じ「SendKeys」というだけで、中身の処理は全然違ったという事を最近使ってみて知ったんですけどね。
そういった話も含めてSeleniumを使ってみて良かった点や気になった点を書いてみようと思います。
- 目次 -
Selenium経由の操作にして良かった点
要素への値の入力
これはすぐ上で書いた「element.SendKeys(value)」というSeleniumの値の入力の仕方についてです。
SendKeysというとアクティブなウィンドウに対してキーストロークを送信するため、
■処理前には対象のウィンドウを最前面にしていないといけない
■動作中にPCは操作してはいけない(誤って違う位置に入力カーソルが動いてしまう可能性があるので)
という気がしますが・・・(VB脳)
実はそんな事は無かった!
SeleniumのSendKeysは自身が作成しているウィンドウに対して直接キーデータを送信してくれるので、ウィンドウは別にアクティブにしていなくても問題ありません。(ちなみにどういう形で送信しているのかは知らない)
更に言うと「ヘッドレスモード」と呼ばれる非表示状態でも、しっかりキーデータは送信されています。初めて知った時は結構衝撃でした。
そしてこのSendKeysを使った場合はjQueryも問題無く動いてくれるので、こちらでKeyUpを強制的に発火させるJavaScriptを実行させなくても良いというのが最大のメリット。
あれ程悩んだメルカリの出品フォームへの入力処理も全て解決しました。(嬉しいんですが、今まで散々悩んだのは何だったんだとちょっと複雑・・・)
<関連記事>
⇒jQueryのchangeイベントをVBAのDOM操作で実行させる方法
⇒KeyboardEventを使ってjQueryのkeyupイベントを実行させる方法
要素の特定が容易
IE操作ではオブジェクト要素の抽出を行う場合、
「getElementById」または「getElementsByTagName」を使い、ループを回しながら目的の要素を探していました。
Seleniumの場合は、
- FindElementByClass()
- FindElementByCss()
- FindElementById()
- FindElementByLinkText()
- FindElementByName()
- FindElementByPartialLinkText()
- FindElementByTag()
- FindElementByXPath()
※FindElement(By.Id()) の書き方でも意味は同じ
ざっと書き出しただけでもオブジェクト要素の抽出方法がこれだけあります。
個人的にFindElementByClassは特に嬉しいですね。
今までのIE操作だと、目的のクラス名を持つ要素を探し出す場合、
objAll = ie.document.getElementsByTagName("hoge") For Each obj In objAll On Error Resume Next className = obj.className On Error GoTo 0 If className = "hoge" Then ' 処理 End If Next
こんな感じでループを回しつつ、クラス名を取得して一致したら処理~なんて処理を要所要所で書いていましたからね・・・
これが見事に1行の処理に置き換えられるのは結構感動しました。まぁ関数化すれば済む話なんですが・・・。
とりあえずすぐに目に付いたのはこの辺。
使い始めてまだ1週間も経っていないので、また使えそうな機能があった場合は使用例も含めて紹介していきます。
Seleniumのここがイマイチ
もちろん良いことばかりでは無かったので、気になった点も幾つか紹介。
既に起動している既存のブラウザが使えない
出来そうかな?という記事は色々見かけたんですが、何か結局出来なさそうな感じ。
「こうすれば出来るよ!」って記事は大体処理上で複数のブラウザを立ち上げていて、『プログラム処理中に立ち上げたブラウザ』のフォーカスを切り替えるみたいな記事だった。(つまりSelenium自身が起動させたブラウザじゃないと管理できない)
うーんそれじゃない。私が知りたかったのはプログラム実行前に既にユーザーが起動しているブラウザを取得するって方法なんだよなぁ。
探し方が悪かっただけで、実はこうすればできるよ!ってのがあれば是非教えて欲しいです。
ちなみに、「なんで既存のブラウザを使い回したいか」というのは後日別の話で取り上げます。
WebDriverを使ったアクセスだとサイト側にバレる
らしいです。
WebDriver経由でアクセスすると、「navigator.webdriver」という値がtrueを返すとか。
ただしこれはブラウザによって挙動が変わるらしく、まだ全てのブラウザが対応している訳では無いらしいです。
それに、サイト側も対応する処理を入れる必要があるみたいなのでブロックするかどうかはサイト次第という事ですね。
しかしこれが標準になってしまうと、今後Seleniumを用いたスクレイピングツール何かが弾かれてしまう可能性が出てくる。
ショッピングサイトを巡回して商品情報を取得するツールは結構作成しているので、ブロックされてしまうと結構痛いかもしれない・・・。
まぁ仮にそうなった場合は原点回帰(IE操作)すれば良いだけですけどね。
あっちだとバレないですし。
最後に
Seleniumが思った以上に便利だった事に驚きました。
mshtmlのIE操作をしていた方であればすぐに移行できると思いますので、ぜひ触ってみる事をおすすめします。
後、Seleniumを触って久しぶりに制作欲が湧いてきたので、Selenium利用して何かツールを作ってみようと思います。
とりあえず・・・メルカリ用の自動出品ツールVer.3かな・・・Ver2以前のIE、Webbrowserコントロール操作版は色々と問題が有りすぎた。