SeleniumでJavaScriptを実行した場合の変数のスコープ

変数のスコープ

SeleniumからJavaScriptを実行する場合、executeScriptメソッドを利用しますが、ローカル変数はメソッド内でのみ有効であることに注意が必要です。

ローカル変数

エラーケース

このスクリプトはエラーになります。

driver.execute_script('var abc = 123;')
driver.execute_script('document.write(abc);')

エラーメッセージ

selenium.common.exceptions.JavascriptException: Message: javascript error: abc is not defined
OKケース

1行で書けば実行できます。

driver.execute_script('var abc = 123; document.write(abc);')

実行結果

123

エラー原因

JavaScriptのarguments.calleeを利用して、実行コードの内容を出力します。

code = 'var abc = 123; document.write(abc); return arguments.callee.toString();'
out = driver.execute_script(code)
print(out)

実行結果

async function(){var abc = 123; document.write(abc); return arguments.callee.toString();}

Seleniumから渡したコードが、関数として実行されていることが分かります。
よって、ローカル変数はexecute_scritメソッド内においてのみ有効です。

グローバル変数

グローバル変数は、複数のexecuteScriptメソッド間で有効です。

driver.execute_script('abc = 123;')
driver.execute_script('document.write(abc);')

実行結果

123

元の変数の上書き

元のHTMLファイルの変数を上書きすることも可能です。
よって、executeScriptメソッドでJavaScriptのグローバル変数を扱うときは、HTML側と変数が競合しないように注意する必要があります。

driver.get('js1.html')
driver.execute_script('document.write(abc + "<br>");')
driver.execute_script('abc = 123;')
driver.execute_script('document.write(abc + "<br>");')
js1.html
<html>
    <body>
        <script>
            var abc=111;
        </script>
    </body>
</html>
実行結果
111 123