Seleniumが要素を配置できない9つのソリューション
8105 ワード
一、frame/iframeフォームネスト
WebDriverは1つのページでのみ要素の識別と位置決めが可能で、frame/iframeフォームに埋め込まれているページ要素は直接位置決めできません.解決方法:
二、ページが新しいラベルページにジャンプしたり、ポップアップされた警告ボックスなど
ページ操作中にリンクをクリックすると新しいウィンドウがポップアップされる場合があります.この場合、新しいウィンドウにフォーカスを切り替えて操作する必要があります.解決策1:
三、ページ要素が焦点を失って、スクリプトの運行が不安定になる
解決方法:
その結果、この操作は入力ボックスに焦点を失い、直接消え、send_keysが入ってきて、直接間違いを報告しました.
四、XpathまたはCSSで位置決めする
五、ページがまだロードされていないのに、ページ上の要素に対する操作
要素のロード遅延によるスクリプトの失敗により、待機時間を設定することで、自動化スクリプトの安定性を向上させることができます.解決策1:
すなわち、
最長待ち時間は5 sで、id='kw'の要素がDOMツリーにロードされているかどうかを1秒おきにチェックします(要素が必ず見えるわけではありません).最も一般的なmethodはexpected_ですconditionsクラスが提供する予想条件判断.
最長待ち時間は30 sで、id='someId'の要素がDOMツリーから消えているかどうかを1秒ごとにチェックし、デフォルトの例外情報NoSuchElementExceptionと指定された例外情報ElementNotVisibleExceptionを無視します.ここで匿名関数
六、要素が遮られ、使用できない、表示されない
解決方法1:
七、WebDriverを使ってJavaScriptコードを呼び出して実現できない機能の代わりにする
WebDriverが提供していない方法や実現できない機能の中には、JavaScriptコードを実行するための
以上の文は、ページの下部を引っ張る機能を実現しており、
入力ボックスがid='text'で位置決めできるがsend_keys()テキストの内容を入力し、JavaScriptコードで実現できます.
以上、HTML 5の画面ラベルの一部テストを実現しましたが、詳細はHTML DOM Videoオブジェクトを参照してください.ここでargumentsはJavaScriptの内蔵オブジェクトです.ビデオオブジェクトがarguments[0]に渡されるため、arguments[0]はJavaScriptスクリプトの
八、WebDriverはWindowsコントロールを操作できない
ファイルの一般的なアップロードとダウンロード(How to auto save files using custom Firefox profile?を参照)、
九、リソースがJavaScriptでロードされた場合https://www.jianshu.com/p/de5e779048de////
十、firefoxは安全性が強く、ドメイン間呼び出しでエラーを報告することは許されない
エラー記述:uncaught exception:[Exception..."Component returned failure code:0 x 800045(NS_ERROR_FAILURE)[nsIDOMNSHTML Document.execCommand]]nsresult:[0 x 80004005(NS_ERROR_FAILURE)]location:解決策:FirefoxがXMLhttpRequestのドメイン間制限を取り消すには、about:configからsignedを設定することが第1です.applets.codebase_principal_support = true; (アドレスバーabout:configを入力するとfirefox設定ができます);2つ目はopenのコード関数の前に次のようなコードを追加することです.
WebDriverは1つのページでのみ要素の識別と位置決めが可能で、frame/iframeフォームに埋め込まれているページ要素は直接位置決めできません.解決方法:
driver.switch_to.frame(
id/name/obj
)
.switch_to.frame()のデフォルトでは、フォームのidまたはnameプロパティを直接取得できます.使用可能なidおよびnameプロパティがない場合は、frame/iframeにナビゲートしてからswitch_にナビゲートできます.to.frame(オブジェクト)メソッド.xf = driver.find_element_by_xpath('//*[@class="if"]')
driver.switch_to.frame(xf)
...
driver.switch_to.parent_frame()
親frameにカットします.パフォーマンスに影響を与え、開発に提案し、改善させることができます.driver.switch_to.default_content()
最外層のページに戻る二、ページが新しいラベルページにジャンプしたり、ポップアップされた警告ボックスなど
ページ操作中にリンクをクリックすると新しいウィンドウがポップアップされる場合があります.この場合、新しいウィンドウにフォーカスを切り替えて操作する必要があります.解決策1:
driver.switch_to.window(
window_handle
)
新しいウィンドウに切り替えます.まず、現在のウィンドウのハンドルdriver.current_window_handle
を取得し、次に、ポップアップされた新しいウィンドウを開き、現在開いているすべてのウィンドウのハンドルdriver.window_handles
を取得する.forループhandleを介して、最初にウィンドウを開いたハンドルに等しくない場合は、実行プロセスが2つのウィンドウしか開いていないため、新しいウィンドウのハンドルに違いありません.条件を変更して、最初に開いたウィンドウのハンドルに等しい場合は、最初に開いたウィンドウに戻ることができます.解決方法2:JavaScriptで生成されたalert、confirmおよびpromptに対して、フロントエンドツールを使用してポップアップウィンドウを位置決めできない場合は、driver.switch_to.alert
メソッドを使用してポップアップボックスを位置決めします.alertの方法は次のとおりです..accept() ' “ ” “OK”'
.dismiss() ' “ ” “Cancel”'
.text ' alert , alert '
.send_keys(text) ' , prompt '
.authenticate(username,password) ' , alert'
三、ページ要素が焦点を失って、スクリプトの運行が不安定になる
解決方法:
driver.switch_to.active_element
スクリプトが不安定で、フォーカスが失われてテストに失敗する場合があります.フォーカス要素をカットしてから操作できます.注意active_elementの後ろに括弧()はありません.次は参考例です.' “ → → ” '
l = driver.find_element_by_id('pm_treeRoom_1_span')
ActionChains(driver).context_click(l).perform()
driver.find_element_by_class_name('fnew').click()
time.sleep(2)
driver.find_element_by_xpath('//*[@id="pm_treeRoom_1_ul"]/li[...]').send_keys('filename')
time.sleep(2)
その結果、この操作は入力ボックスに焦点を失い、直接消え、send_keysが入ってきて、直接間違いを報告しました.
' '
driver.find_element_by_class_name('fnew').click()
time.sleep(2)
driver.switch_to.active_element.send_keys('filename')
time.sleep(2)
四、XpathまたはCSSで位置決めする
find_element_by_xpath("// [ =' ']")
Xpath/CSSメソッドを使用すると、位置決め属性値が動的に生成され、位置決めが容易でない要素に非常に適しています.ラベルを指定したくない場合は、id、name、classの3つの属性に限定されずxpathを使用する代わりに、要素の任意の属性値を使用できます.要素を一意に識別できる限り.解決方法1:エレメントに一意のプロパティがない場合は、エレメントを一意に配置できるプロパティが見つかるまで、サブエレメントを下に検索します.find_element_by_xpath("//form[@id='form']/span[2]/input")
は、まず属性id=formを一意に識別することによって最外層要素を位置決めし、次に最外層要素の下の2番目のspanラベルの要素を親要素とし、最後に親要素の下のラベルがinputであるサブ要素を下に検索する.解決方法2:1つの属性が1つの要素を一意に区別できない場合は、複数の属性を使用して1つの要素を一意に配置します.find_element_by_xpath("//input[@id='kw' and @class='su']/span/input")
は、まず、ラベルがinput、id=kw、class=suの要素を見つけ、次に、ラベルがspanのサブ要素を見つけ、ラベルがinputのサブ要素を下に探し続けます.解決方法3:Xpath記述に誤りがないかを確認し、要素に位置決めできない.五、ページがまだロードされていないのに、ページ上の要素に対する操作
要素のロード遅延によるスクリプトの失敗により、待機時間を設定することで、自動化スクリプトの安定性を向上させることができます.解決策1:
WebDriverWait()
は待機を示す.単一の要素のロードを待機し、通常はuntil()
、until_not()
の方法と組み合わせて使用される.WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
- driver - WebDriver ,
- timeout - ,
- poll_frequency - `until`/`until_not` , 0.5 , 。
- ignored_exceptions - , NoSuchElementException, 。
WebDriverWait(driver,10).until(method,message='') ' '
WebDriverWait(driver,5,1).until_not(method,message='') ' '
- method - 。
- message - , 。 , TimeoutException, message 。
すなわち、
WebDriverWait(driver, , , ).until( , )
WebDriverWait(driver,5,1).until(expected_conditions.presence_of_element_located(By.ID,'kw'))
最長待ち時間は5 sで、id='kw'の要素がDOMツリーにロードされているかどうかを1秒おきにチェックします(要素が必ず見えるわけではありません).最も一般的なmethodはexpected_ですconditionsクラスが提供する予想条件判断.
is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).until_not(lambda x: x.find_element_by_id('someId').is_displayed())
最長待ち時間は30 sで、id='someId'の要素がDOMツリーから消えているかどうかを1秒ごとにチェックし、デフォルトの例外情報NoSuchElementExceptionと指定された例外情報ElementNotVisibleExceptionを無視します.ここで匿名関数
lambda
の使い方はPython構文を参照してください.解決策2:driver.implicitly_wait( )
暗黙的待ち時間.グローバル待機、すべての要素にタイムアウト時間を設定し、ページのロードを待機するため、一度だけ設定する必要があります.ここでの時間は最長待ち時間(非固定待ち時間)です.解決策3:sleep( )
スレッド待ち.スリープ固定時間は、timeモジュールのsleepメソッドfrom time import sleep
を先に導入する必要がある.六、要素が遮られ、使用できない、表示されない
解決方法1:
driver.maximize_window()
ウィンドウサイズの変化によるページ要素のレイアウトが変化し、被測定要素が遮断され、まずウィンドウを最大化してから要素の位置決めを行うことができる.解決策2:.is_enabled()
ビジネス上の理由で要素が使用できない場合(要素属性disabled、グレー表示)は、まずテストステップがビジネスロジックに合致するかどうかを確認し、次にビジネスプロセス上のBugであるかどうかを確認します.解決策3:.is_displayed()
属性が必ずしも見えるとは限らない要素については,位置決め前にまずその属性が見えるか,隠されているかを判断する.解決方法4:レイアウトの不合理による要素の隠蔽、または要素自体の欠落による位置決め不能の問題はBugに属し、開発に改善をもたらすことができる.七、WebDriverを使ってJavaScriptコードを呼び出して実現できない機能の代わりにする
WebDriverが提供していない方法や実現できない機能の中には、JavaScriptコードを実行するための
driver.execute_script()
の方法が用意されています.解決策:ページの内容が長すぎると、ウィンドウが最大化されてもすべての要素が表示されなくなり、JavaScriptスクリプトを実行することでスクロールバーのドラッグなどの動作を実現できます.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
以上の文は、ページの下部を引っ張る機能を実現しており、
window.scrollTo( , )
は、JavaScriptでブラウザウィンドウのスクロールバーの水平位置と垂直位置を設定するためのコードです.text = "input text"
driver.execute_script("var obj=document.getElementById('text'); obj.value=' " + text + " ';")
入力ボックスがid='text'で位置決めできるがsend_keys()テキストの内容を入力し、JavaScriptコードで実現できます.
video = driver.find_element_by_xpath("body/Section[1]/div/video")
url = driver.execute_script("return arguments[0].currentSrc;", video)
print(url) ' '
print("start") ' '
driver.execute_script("return arguments[0].play()", video)
sleep(15) ' 15 '
print(stop) ' '
driver.execute_script("arguments[0].pause()", video)
...
以上、HTML 5の画面ラベルの一部テストを実現しましたが、詳細はHTML DOM Videoオブジェクトを参照してください.ここでargumentsはJavaScriptの内蔵オブジェクトです.ビデオオブジェクトがarguments[0]に渡されるため、arguments[0]はJavaScriptスクリプトの
document.getElementsByTagName("video")
に相当する.JavaScriptではリロードはサポートされていません.argumentsオブジェクトを使用すると、関数のリロード効果をシミュレートできます.八、WebDriverはWindowsコントロールを操作できない
ファイルの一般的なアップロードとダウンロード(How to auto save files using custom Firefox profile?を参照)、
.send_keys(' ')
およびfind_element_by_partial_link_text(' ').click()
によって実現することができる.解決方法:プラグインのアップロードに対してWindowsコントロールを操作する必要がある場合、AutoItツールのインストール、スクリプトの作成、「.au 3」ファイルの保存、「.exe」ファイルへの変換、自動化スクリプトos.system("D:\\upfile.exe")
によるアップロード/ダウンロードを実現することができる.* 、 , 。 python exe python , , , 。
九、リソースがJavaScriptでロードされた場合https://www.jianshu.com/p/de5e779048de////
十、firefoxは安全性が強く、ドメイン間呼び出しでエラーを報告することは許されない
エラー記述:uncaught exception:[Exception..."Component returned failure code:0 x 800045(NS_ERROR_FAILURE)[nsIDOMNSHTML Document.execCommand]]nsresult:[0 x 80004005(NS_ERROR_FAILURE)]location:解決策:FirefoxがXMLhttpRequestのドメイン間制限を取り消すには、about:configからsignedを設定することが第1です.applets.codebase_principal_support = true; (アドレスバーabout:configを入力するとfirefox設定ができます);2つ目はopenのコード関数の前に次のようなコードを追加することです.
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
}
catch (e) {
alert("Permission UniversalBrowserRead denied.");
}