Santiは、Seleniumが指定されたロケーターに一致する最初の要素を返すということは正しいです。使用するロケータータイプの適切な式を適用する必要があります。ここで詳細を説明すると便利だと思いましたが、この場合、彼らは「残酷な詳細」であることに国境を接しています。
CSS
:nth-child
疑似クラスの使用には注意が必要です。W3Cページでさえ、ほとんど知られていない、明確に文書化されていない微妙な点があります。次のようなリストを検討してください。
<ul>
<li class="bird">petrel</li>
<li class="mammal">platypus</li>
<li class="bird">albatross</li>
<li class="bird">shearwater</li>
</ul>
次に、セレクターはせん断水ではなくアホウドリ要素をcss=li.bird:nth-child(3)
返します!この理由は、最初に一致する要素の兄弟である要素のリストにインデックス(3)を使用するためです。これは、.birdクラスによってフィルタリングされていません。正しい要素(この例では3番目の要素)を取得すると、鳥のクラスフィルターを適用します。手元の要素が一致する場合は、それを返します。そうでない場合は、一致しません。
次に、セレクターについて考えcss=li.bird:nth-child(2)
ます。これは、2番目の要素であるカモノハシから始まります。これは鳥ではなく、空になっていることを確認します。これは、コードが「見つかりません」例外をスローすることで明らかになります。
インデックス付きエントリを見つける典型的なメンタルモデルに適合するのは、インデックスを作成する前:nth-of-type
にフィルタを適用するCSS疑似クラスです。残念ながら、ロケーターに関する公式ドキュメントによると、これはSeleniumではサポートされていません。
XPath
あなたの質問は、XPathでこれを行う方法を知っていることをすでに示しています。式の任意の場所に角かっこで配列参照を追加します。たとえば、次のようなものを使用でき//*[@id='abc']/div[3]/p[2]/span
ます。指定されたIDの下の3番目のdivの下の2番目の段落でスパンを検索します。
DOM
DOMはXPathと同じ角括弧表記を使用しますが、DOMはゼロからインデックスを作成し、XPathは1からインデックスを作成しますdocument.getElementsByTagName("div")[1]
。最初のdivではなく2番目のdivを返します。DOMは代替構文も提供します:document.getElementsByTagName("div").item(0)
まったく同等です。また、getElementsByTagNameでは、単一のノードではなくノードセットを返すため、常にインデックスを使用する必要があることに注意してください。