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

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

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

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

selenium

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

Q&A

解決済

1回答

913閲覧

C#+SeleniumでStaleElementReferenceError

masahiro.o

総合スコア16

Chrome

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

selenium

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

0グッド

0クリップ

投稿2018/04/20 08:19

C#でSeleniumを使用して自動化処理を書いています。
(ブラウザはChromeです。)

OS: Windows10
IDE: Visual Studio 2015
Selenium: 3.11.2
ChromeDriver: 2.37.0

必ずではないのですが、頻繁に「stale element reference: element is not attached to the page document」という
StaleElementReferenceErrorが発生して困っています。

例えば、特定のaタグをクリックする処理で、DisplayedもtrueでTextの値も取れる状態でClickすると発生したりします。

色々調べたのですが、完全に描画されるまで待つしかなさそうで
以下のようにWebDriverWaitで待ってみたりしても不安定です…

C#

1 private static IWebElement FindElementEx(By by, uint timeOutInSeconds) 2 { 3 if (timeOutInSeconds > 0) 4 { 5 var wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(timeOutInSeconds)); 6 return wait.Until<IWebElement>(ctx => ctx.FindElement(by)); 7 } 8 return webDriver.FindElement(by); 9 } 10

仕方なく上の処理で要素を取得して、Sleep(1000)などとして回避していますが
もっとスマートなやり方はございませんでしょうか。

知っている方がいらっしゃればご教示お願いいたします。

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

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

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

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

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

guest

回答1

0

自己解決

stack over flowにそれっぽいのがあったので一先ず解決にします。
(これでもダメなときはダメですがマシにはなりました。)
需要があるかは分かりませんが一応、共有しておきます。

以下の拡張クラスをプロジェクトに追加します。

C#

1 /// <summary> 2 /// Method that finds an element based on the search parameters within a specified timeout. 3 /// </summary> 4 /// <param name="context">The context where this is searched. Required for extension methods</param> 5 /// <param name="by">The search parameters that are used to identify the element</param> 6 /// <param name="timeOutInSeconds">The time that the tool should wait before throwing an exception</param> 7 /// <returns> The first element found that matches the condition specified</returns> 8 public static IWebElement FindElement(this ISearchContext context, By by, uint timeOutInSeconds) 9 { 10 if (timeOutInSeconds > 0) 11 { 12 var wait = new DefaultWait<ISearchContext>(context); 13 wait.Timeout = TimeSpan.FromSeconds(timeOutInSeconds); 14 return wait.Until<IWebElement>(ctx => ctx.FindElement(by)); 15 } 16 return context.FindElement(by); 17 } 18 /// <summary> 19 /// Method that finds a list of elements based on the search parameters within a specified timeout. 20 /// </summary> 21 /// <param name="context">The context where this is searched. Required for extension methods</param> 22 /// <param name="by">The search parameters that are used to identify the element</param> 23 /// <param name="timeoutInSeconds">The time that the tool should wait before throwing an exception</param> 24 /// <returns>A list of all the web elements that match the condition specified</returns> 25 public static IReadOnlyCollection<IWebElement> FindElements(this ISearchContext context, By by, uint timeoutInSeconds) 26 { 27 28 if (timeoutInSeconds > 0) 29 { 30 var wait = new DefaultWait<ISearchContext>(context); 31 wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds); 32 return wait.Until<IReadOnlyCollection<IWebElement>>(ctx => ctx.FindElements(by)); 33 } 34 return context.FindElements(by); 35 } 36 /// <summary> 37 /// Method that finds a list of elements with the minimum amount specified based on the search parameters within a specified timeout.<br/> 38 /// </summary> 39 /// <param name="context">The context where this is searched. Required for extension methods</param> 40 /// <param name="by">The search parameters that are used to identify the element</param> 41 /// <param name="timeoutInSeconds">The time that the tool should wait before throwing an exception</param> 42 /// <param name="minNumberOfElements"> 43 /// The minimum number of elements that should meet the criteria before returning the list <para/> 44 /// If this number is not met, an exception will be thrown and no elements will be returned 45 /// even if some did meet the criteria 46 /// </param> 47 /// <returns>A list of all the web elements that match the condition specified</returns> 48 public static IReadOnlyCollection<IWebElement> FindElements(this ISearchContext context, By by, uint timeoutInSeconds, int minNumberOfElements) 49 { 50 var wait = new DefaultWait<ISearchContext>(context); 51 if (timeoutInSeconds > 0) 52 { 53 wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds); 54 } 55 56 // Wait until the current context found the minimum number of elements. If not found after timeout, an exception is thrown 57 wait.Until<bool>(ctx => ctx.FindElements(by).Count >= minNumberOfElements); 58 59 //If the elements were successfuly found, just return the list 60 return context.FindElements(by); 61 }

使い方は以下のような感じです。

C#

1ar driver = new FirefoxDriver(); 2driver.Navigate().GoToUrl("http://localhost"); 3var main = driver.FindElement(By.Id("main")); 4// It can be now used to wait when using elements to search 5var btn = main.FindElement(By.Id("button"),10); 6btn.Click(); 7//This will wait up to 10 seconds until a button is found 8var button = driver.FindElement(By.TagName("button"),10) 9//This will wait up to 10 seconds until a button is found, and return all the buttons found 10var buttonList = driver.FindElements(By.TagName("button"),10) 11//This will wait for 10 seconds until we find at least 5 buttons 12var buttonsMin= driver.FindElements(By.TagName("button"), 10, 5); 13driver.Close();

色々やったのですが、上の対応を行いまだエラーが出る場合はSleepを少し入れるなどの対応で回避しています。
あまり試せていませんが、ボタンやリンクなどのクリックはJavaScriptでクリックするように仕込んだ方が安定するかもしれません。

C#でSelenium触ってる人は少ないんですかね…日本語の情報少ないです。

投稿2018/04/22 07:16

masahiro.o

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問