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

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

ただいまの
回答率

90.37%

  • Java

    16499questions

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

  • Chrome

    821questions

    Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

  • selenium

    773questions

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

ヘッダー固定のキャプチャをきれいに撮りたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 139

jin007

score 15

実現したい事

seleniumを使ってヘッダーが固定されているサイトのキャプチャをきれいに撮れるようにしたい

現状

ヘッダーが固定されていて邪魔。
イメージ説明

環境

selenium 2.45.0
Java 1.8
Chrome 73.0.3683.103

参考サイト

こちら

現在のソース

WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get(baseUrl + "/sample.html");
        driver.switchTo().defaultContent();
        TakesScreenshot ts = (TakesScreenshot) new Augmenter().augment(driver);

        //JS実行用のExecuter
        JavascriptExecutor jexec = (JavascriptExecutor) driver;

        //画面サイズで必要なものを取得
        int innerH = Integer.parseInt(String.valueOf(jexec.executeScript("return window.innerHeight")));
        int innerW =Integer.parseInt(String.valueOf(jexec.executeScript("return window.innerWidth")));
        int scrollH = Integer.parseInt(String.valueOf(jexec.executeScript("return document.documentElement.scrollHeight")));

        //イメージを扱うための準備
        BufferedImage img = new BufferedImage(innerW, scrollH, BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();

        //スクロールを行うかの判定
        if(innerH>scrollH){
            BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
            g.drawImage(imageParts, 0, 0, null);
        } else {
            int scrollableH = scrollH;
            int i = 0;

            //スクロールしながらなんどもイメージを結合していく
            while(scrollableH>innerH){
                BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
                g.drawImage(imageParts, 0, innerH*i, null);
                scrollableH=scrollableH - innerH;
                i++;
                jexec.executeScript("window.scrollTo(0,"+innerH*i+")");
            }

            //一番下まで行ったときは、下から埋めるように貼り付け
            BufferedImage imageParts = ImageIO.read(ts.getScreenshotAs(OutputType.FILE));
            g.drawImage(imageParts, 0, scrollH - innerH, null);
        }

        ImageIO.write(img, "png", new File("c:\\temp\\mergeimg-"+ System.currentTimeMillis() +".png"));

よろしくお願いいたします。

追加画像①
Spotify

追加画像②
CSS

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

スクロールに追従している要素のほとんどはCSSに

position : fixed;


が指定されており、これを

position : absolute;


に書き換えれば、先頭固定になる事が大半ですが、positionをどのセレクターに指定しているかはサイトの仕様により、まちまちなので毎度調べる必要があると思います。

質問文に挿入された画像のサイト(Spotify)に限った話では以下コードで追従は無くなると思います。

jexec.executeScript("document.getElementsByTagName('header')[0].style.position = 'absolute'")

またGoogleの検索結果ページ等は、positionを動的にJavaScriptで書き換えてるので全てのサイトで通用する方法は無いかもしれません。(Javaで画像の連結部分を調整すればできるかもしれませんが)

解決はできませんが、参考までに。


追記

JSでは、element(要素)の取得に以下のメソッドを用います。

複数のelementを、配列ライクなオブジェクト(HTMLCollection)を返す

  • document.getElementsByClassName("クラスの名前")
  • document.getElementsByTagName("タグ名")
  • document.getElementsByName("Name属性")
    ※Elementが複数形でElements

例えば、一番最初のdivであれば、document.getElementsByTagName("div")[0]
二番目のdivであれば、document.getElementsByTagName("div")[1]

として取得できます。

特定の1つのelementを返す

  • document.getElementById("Id")
    ※Elementが単数形

スタイル優先順位、JSによるインラインスタイルの動的変更

HTMLにおいてスタイルはCSSを用いて指定しますが、CSSは様々な場所から様々な方法指定されています。
それにより、1つの要素に対して2つのスタイルが衝突が発生してしまいます。
衝突時は以下の順番で上書きされていきます。(下が最優先)
※一部高度なものは省略します

  1. 全称セレクタによる指定*{color:pink;} 
  2. タグに対する指定 div{color:orange;}
  3. クラスに対する指定 .sample-class-name{color:black;}
  4. idに対する指定 #sample-id{color:blue;}
  5. インラインによる指定 <div style="color:red;"></div>
  6. (!importantによる指定 *{color:pink !important;}
    !importantは特殊で、優先順位を無視し最優先になります。

そして、JavaScriptにおいて、

document.getElementsByClassName("sample-class")[0].style = "position:fixed"

で変更されるのは、上記リストの
 5. インラインによる指定 <div style="color:red;"></div> 
です。これにより、!importantが宣言されていない限り最優先で変更されます。

したがって…

※HTMLの不要な属性は省略しました

<div id="analysisPg-header" class="header ui-header-fixed ui-header ui-bar-inherit">

こいつに、position=absoluteを指定したい場合は、以下のJSになります。

document.getElementById('analysisPg-header').style.position = 'absolute'

このJSを実行すると、htmlは以下のように変化します。

<div id="analysisPg-header" class="header ui-header-fixed ui-header ui-bar-inherit" style="position:absolute;">

上述の通り、このように要素に書かれたスタイル(インラインスタイル)は!important指定が無い限り最優先なので変更されます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/12 11:38 編集

    JavaとJavaScriptがゴチャゴチャになってませんか?
    Java上でレンダリングエンジンを動かして、そいつへJSを文字列として発行しているんですよね?

    【JavaScript内で変数を使う】
    jexec.executeScript("const htmlId = 'エレメントのID'");
    jexec.executeScript("document.getElementById(htmlId).style.position = 'absolute'");

    【Javaの変数からJavaScriptコードに埋め込む例】
    ※Javaはほとんど書いた事無いのでミスあるかもしれません。
    String htmlId = "エレメントのID";
    jexec.executeScript("document.getElementById('"+htmlId+"').style.position = 'absolute'");

    キャンセル

  • 2019/04/12 12:00

    "document.getElementById('"+htmlId+"')

    変数の組み込み方が分からず苦戦していました。
    ()の中でで+を使うんですね!

    指定する方法が分からず苦戦していました。
    ありがとうございます。成功できそうです!

    この方法も気になったので試してみます。
    http://d.hatena.ne.jp/MoonMtLab/20130831/1377919614

    キャンセル

  • 2019/04/12 12:03

    おお、良かったです!
    そちらのURLの物は、Java+JSPでWEBサーバーを作り、JSを返した場合なので、今回とは全く違う話とはなります。挑戦してみるのはありだと思います!

    キャンセル

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

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    16499questions

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

  • Chrome

    821questions

    Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

  • selenium

    773questions

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