web-dev-qa-db-ja.com

Seleniumロケーターで正規表現を使用する方法

私はSeleniumRCを使用しています。たとえば、属性hrefが一致するすべてのリンク要素を取得したいと思います。

http://[^/]*\d+com

使用したい:

sel.get_attribute( '//a[regx:match(@href, "http://[^/]*\d+.com")]/@name' )

これは、正規表現に一致するすべてのリンクのname属性のリストを返します。 (またはそのようなもの)

ありがとう

11
Guy

考えられる解決策は、sel.get_eval()を使用して、リンクのリストを返すJSスクリプトを作成することです。次のような答え: Selenium:Seleniumロケーターで正規表現を使用することは可能ですか

1
Guy

上記の答えは、おそらく正規表現に一致するすべてのリンクを見つける正しい方法ですが、質問の他の部分であるXpathロケーターでの正規表現の使用方法にも答えることが役立つと思いました。次のように、正規表現のmatches()関数を使用する必要があります。

xpath=//div[matches(@id,'che.*boxes')]

(もちろん、これは「id = checkboxes」または「id = cheANYTHINGHEREboxes」でdivをクリックします)

ただし、matches関数はXpathのすべてのネイティブブラウザー実装でサポートされているわけではないことに注意してください(最も顕著に、FF3でこれを使用するとエラーがスローされます:invalid xpath [2])。

特定のブラウザーで問題が発生した場合(FF3で行ったように)、SeleniumのallowNativeXpath( "false")を使用してJavaScriptXpathインタープリターに切り替えてみてください。遅くなりますが、「matches」や「ends-with」など、より多くのXpath関数で機能するようです。 :)

12
Chris Jaynes

SeleniumコマンドgetAllLinksを使用して、ページ上のリンクのIDの配列を取得できます。これをループして、getAttributeを使用してhrefを確認できます。この場合、ロケーターの後に@と属性名が続きます。たとえば、Javaの場合、これは次のようになります。

String[] allLinks = session().getAllLinks();
List<String> matchingLinks = new ArrayList<String>();

for (String linkId : allLinks) {
    String linkHref = Selenium.getAttribute("id=" + linkId + "@href");
    if (linkHref.matches("http://[^/]*\\d+.com")) {
        matchingLinks.add(link);
    }
}
3
Dave Hunt

SeleniumRCの代替方法もいくつかあります。これらは純粋なSeleniumソリューションではなく、プログラミング言語のデータ構造およびSeleniumとの相互作用を可能にします。

HTMLページのソースを取得してから、正規表現のソースを取得して、一致するリンクのセットを返すこともできます。正規表現のグループ化を使用して、URLを分離したり、テキスト/ IDをリンクしたりすると、それらをSeleniumに返して、クリックまたは移動できます。

もう1つの方法は、親/ルート要素のHTMLページソースまたはinnerHTMLを(DOMロケーターを介して)取得し、プログラミング言語のDOMオブジェクトとしてHTMLをXMLに変換することです。次に、目的のXPath(正規表現を使用するかどうかに関係なく)を使用してDOMをトラバースし、対象のリンクのみのノードセットを取得できます。それらからリンクテキスト/ IDまたはURLを解析し、S​​eleniumに戻ってクリックまたは移動できます。

リクエストに応じて、以下に例を示します。投稿はとにかく言語固有ではないようだったので、それは混合言語です。例として、一緒にハッキングするために利用できるものを使用しています。これらは完全にはテストされておらず、まったくテストされていませんが、他のプロジェクトで以前にコードの一部を使用したことがあるので、これらは、今述べたソリューションを実装する方法の概念実証コードの例です。

//Example of element attribute processing by page source and regex (in PHP)
$pgSrc = $sel->getPageSource();
//simple hyperlink extraction via regex below, replace with better regex pattern as desired
preg_match_all("/<a.+href=\"(.+)\"/",$pgSrc,$matches,PREG_PATTERN_ORDER);
//$matches is a 2D array, $matches[0] is array of whole string matched, $matches[1] is array of what's in parenthesis
//you either get an array of all matched link URL values in parenthesis capture group or an empty array
$links = count($matches) >= 2 ? $matches[1] : array();
//now do as you wish, iterating over all link URLs
//NOTE: these are URLs only, not actual hyperlink elements

//Example of XML DOM parsing with Selenium RC (in Java)
String locator = "id=someElement";
String htmlSrcSubset = sel.getEval("this.browserbot.findElement(\""+locator+"\").innerHTML");
//using JSoup XML parser library for Java, see jsoup.org
Document doc = Jsoup.parse(htmlSrcSubset);
/* once you have this document object, can then manipulate & traverse
it as an XML/HTML node tree. I'm not going to go into details on this
as you'd need to know XML DOM traversal and XPath (not just for finding locators).
But this tutorial URL will give you some ideas:

http://jsoup.org/cookbook/extracting-data/dom-navigation

the example there seems to indicate first getting the element/node defined
by content tag within the "document" or source, then from there get all
hyperlink elements/nodes and then traverse that as a list/array, doing
whatever you want with an object oriented approach for each element in
the array. Each element is an XML node with properties. If you study it,
you'd find this approach gives you the power/access that WebDriver/Selenium 2
now gives you with WebElements but the example here is what you can do in
Selenium RC to get similar WebElement kind of capability
*/
0
David