質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

2回答

5744閲覧

表示しているページのサイズ(画面キャプチャのサイズ、もしくは類似のサイズ)をselenumの何かしらのクラスで取得する方法

tasuku

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

0クリップ

投稿2015/10/08 07:49

seleniumで、巨大なページの画面キャプチャを取得するとOutOfMemoryが発生してしまいます。
短時間で大量のJavaヒープを消費するためOutOfMemoryErrorになっているようなので、
巨大なページであればキャプチャを取らないように条件分岐させたいと思っています。

** そこで表示したページのサイズ(画面キャプチャのサイズ、もしくは類似のサイズ)をselenumの何かしらのクラスで取得する方法**
をご存知な方いらっしゃいましたらお教え頂きたいです。

▼具体的な問題▼
具体的には、
http://backyard.imjp.co.jp/static/feed/atom.xml
を以下のコードで画面キャプチャを採取しようとするとOutOfMemoryが発生します。

▼キャプチャ採取のコード▼

//取得したURLのスクリーンショット作成 File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(scrFile, new File(scrFileName));

▼発生している例外▼

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.lang.StringCoding.decode(StringCoding.java:215) at java.lang.String.<init>(String.java:451) at java.lang.String.<init>(String.java:503) at org.openqa.selenium.remote.http.HttpMessage.getContentString(HttpMessage.java:110) at org.openqa.selenium.remote.http.HttpResponse.getContentString(HttpResponse.java:1) at org.openqa.selenium.remote.http.JsonHttpResponseCodec.decode(JsonHttpResponseCodec.java:76) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:137) at org.openqa.selenium.firefox.internal.NewProfileExtensionConnection.execute(NewProfileExtensionConnection.java:170) at org.openqa.selenium.firefox.FirefoxDriver$LazyCommandExecutor.execute(FirefoxDriver.java:393) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:568) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:618) at org.openqa.selenium.firefox.FirefoxDriver.getScreenshotAs(FirefoxDriver.java:354) at sample.SandBox.main(SandBox.java:168)

▼試してみたけどダメだったこと▼
0. JVMの起動パラメータで、-Xms1024m、-Xmx1024mにした。
0. ファイルコピーをせずに一時ディレクトリでのキャプチャ採取のみにした。(FileUtils.copyFile(scrFile, new File(scrFileName)); をコメントアウト)

▼やりたいこと。質問▼
短時間で大量のJavaヒープを消費するためOutOfMemoryErrorになっているようなので、
巨大なページの画面キャプチャ採取をあきらめ、
巨大なページであればキャプチャを取らないように条件分岐させたいと思っています。

** そこで表示したページのサイズ(画面キャプチャのサイズ、もしくは類似のサイズ)をselenumの何かしらのクラスで取得する方法**
をご存知の方はお教え頂きたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

skyfishさんに伺った以下の方法でJSを動かしてスクロールするサイズを取得することで、
サイズの大きいページを判定することができました。
(実際には若干お教え頂いたコードとは異なってましたがそこは推測できる範囲なので大丈夫でしたw)

Java

1//skyfishさんに伺った方法 2int scrollLength = Integer.parseInt(((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight").toString());

ですが、JSを実行しなくても、selenium自体(org.openqa.selenium.Dimension)でスクロールした時のサイズが以下取れることがわかりました。

Java

1//selenium自体(org.openqa.selenium.Dimension)を使う方法 2Dimension rootDomSize = driver.findElement(By.tagName("body")).getSize(); 3int height = rootDomSize.height; 4int width = rootDomSize.width;

skyfishさんにお教え頂いた方法とorg.openqa.selenium.Dimensionを使う方法と値を比較してみましたが以下で一緒でした。

java

1//2つの方法の値比較 2 int scrollLength = Integer.parseInt(((JavascriptExecutor) driver).executeScript("return document.body.scrollHeight").toString()); 3 Dimension rootDomSize = driver.findElement(By.tagName("body")).getSize(); 4 System.out.println("height:"+rootDomSize.height+" width:"+rootDomSize.width+" scrollLength:"+scrollLength); 5 6結果: 7height:38780 width:1407 scrollLength:38780 8

中身は同じことしてるのかもしれませんが、一応JS呼び出すよりもJava内で実行できたほうがいいかなと思い、後者を使って以下のようにすることにしました。

java

1 if (driver instanceof JavascriptExecutor) { 2 Dimension rootDomSize = driver.findElement(By.tagName("body")).getSize(); 3 //長さが2万px以下の時はそのままスクリーンショットを撮る 4 if(rootDomSize.height >= 20000){ 5 6 //取得したURLのスクリーンショット作成 7 File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); 8 FileUtils.copyFile(scrFile, new File(scrFileName)); 9 10 } 11 }

ただ、ちょっとこれだと逃げてる感があるので、
サイズの大きい画面では、画面サイズを小さくしてキャプチャを採取することにしました。

java

1 //ウィンドウサイズを小さくする 2 driver.manage().window().setSize(new Dimension(100,100)); 3

結果は、成功しました!
ですが、画面サイズを元に戻さないと次のキャプチャ採取の時に、
小さいままになってしまうので、その辺りがちょっと面倒。。。

今度は、サイズの大きい画面では、
スクロールしないで表示されているところだけキャプチャするようにできないか試したく、
また質問しちゃってます↓
FirefoxDriverでスクロールさせないでキャプチャする方法

ということでアドバイスありがとうございました!!

投稿2015/10/09 03:01

tasuku

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

SeleniumというよりWebDriver側の機能ですが、
WebDriverに向けてjavascriptのコードを叩いて値を返してもらう事で実装できます。

java

1int scrollLength = Integer.parseInt(webdriver.execute_script("return document.body.scrollHeight")); 2System.out.println(scrollLength); 3if(scrollLength < 100000){ 4 //長さが10万以下の時はスクリーンショットを撮る 5}

上記のようにして得られたscrollLengthの値がいくら以下の時はSSを取る。
みたいに実装すると良いのではないでしょうか。

面白い内容だったので動くコードをgithubに残しました。rubySeleniumですが参考までに
https://github.com/Lyptica/seleniumScrollTest/blob/master/seleniumScroll.rb

参考:
Efficient method to scroll though pages using Selenium
http://stackoverflow.com/questions/19803963/efficient-method-to-scroll-though-pages-using-selenium

投稿2015/10/08 10:11

編集2015/10/08 10:15
SKYYFISH

総合スコア654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tasuku

2015/10/09 01:30

おー。 webdriverにjsを実行させるメソッドがあるんですね(webdriver.execute_script) 本題とはちがったことが学べて得した気分です。 早速試してみます。 PS:Rubyも勉強しなくては。。。w
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問