2015-10-11 48 views
1

找到,如果佈局具有特定文本視圖或我有這樣的線性佈局不

enter image description here

現在有些線性佈局有子類別,一些不具備的。相似的一些有折扣,而且沒有。

所以,當我做這樣的事情:

List<WebElement> allFieldsInLayout = driver.findElements(By.id("com.flipkart.android:id/product_list_product_item_layout")); 
List<WebElement> allTitlesOnCurrentScreen = driver.findElements(By.xpath("//*[@resource-id='com.flipkart.android:id/product_list_product_item_main_text']")); 
List<WebElement> allsubTitlesOnCurrentScreen = driver.findElements(By.xpath("//*[@resource-id='com.flipkart.android:id/product_list_product_item_sub_text']")); 
List<WebElement> allOfferPricesOnCurrentScreen = driver.findElements(By.xpath("//*[@resource-id='com.flipkart.android:id/product_list_product_item_price']")); 
List<WebElement> allListPriceOnCurrentScreen = driver.findElements(By.xpath("//*[@resource-id='com.flipkart.android:id/product_list_product_item_mrp']")); 

,然後嘗試打印在他們裏面的文字:

for(int i=0;i<allTitlesOnCurrentScreen.size();i++){ 

     System.out.println("TITLE : "+allTitlesOnCurrentScreen.get(i).getAttribute("text") 
         + "SUB TITLE : "+allsubTitlesOnCurrentScreen.get(i).getAttribute("text") 
         + "OFFER PRICE : "+allOfferPricesOnCurrentScreen.get(i).getAttribute("text") 
         + "LIST PRICE : "+allListPriceOnCurrentScreen.get(i).getAttribute("text") 
     ); 
    } 

我陣列外邊界異常。所以我想如果它有可能從這個列表的外部佈局獲得所有子字段的資源ID。我想是這樣的:

for(int i=0;i<allFieldsInLayout.size();i++){ 
      List<WebElement> allElementsinCurrentLayout = allFieldsInLayout.get(i).findElements(By.xpath("//android.widget.RelativeLayout[@index='2']")); 
      for(int j=0;j<allElementsinCurrentLayout.size();j++) { 
       System.out.println("Layout " + allElementsinCurrentLayout.get(j)); 
      } 
} 

但它給不同的是

Cannot use xpath locator strategy from an element. It can only be used from the root element) 

我想在我的名單NULL,如果我沒有對應的子標題,或者如果沒有折扣是存在的。怎麼做 ?

+0

爲什麼你用這種方法找到每一個項目?通過它的ID(或名稱,標籤等)查找每個項目可能更容易,如果您在此尋找它可以找到不同的方法來完成它。 –

+0

@GastonF。你在說什麼方法? – GitCoder

+0

[Here](http://www.codota.com/android/methods/android.app.Activity/findViewById)有一些使用findViewById的示例。 [Here](http://stackoverflow.com/a/6831562/1563878)按資源名稱查找。 [Here](http://stackoverflow.com/questions/8817377/android-how-to-find-multiple-views-with-common-attribute)其他方法。 –

回答

0

一般來說,我處理這類問題的方式是找到包含單個產品所有產品信息的最頂層元素。將這些元素作爲集合返回並遍歷它。在每次迭代中,查找包含元素的不同信息...檢查存在並獲取數據(如果存在)。這種方法將允許您整齊地捕獲每個產品的所有屬性/數據作爲一個包。

您的方法存在的問題是您正在存儲數據元素,例如,字幕,與產品分開。因此,想象一下,如果您的網頁上有4種產品,並且只有2種產品帶有字幕。你循環瀏覽4種產品(通過索引)訪問字幕......你將遇到2個問題:1)你會跑掉字幕數組的末尾,因爲只有2個,而你正在循環到4個。2)你的字幕陣列將與產品陣列中的產品不匹配。

想象這是您的網頁

Product1 
Subtitle1 

Product2 

Product3 
Subtitle3 

Product4 

你的產品陣列將包含:產品1,產品2,產品3,產品4

你的陣列字幕將包含:Subtitle1,Subtitle3

所以當使用該產品索引您循環您將獲得:

Product1, Subtitle1 
Product2, Subtitle3 // notice the mismatch 2 and 3 
Product3, Array out of index error 

所以你跑掉了你的字幕數組的末尾,你的字幕不匹配相應的產品。希望這個例子更有意義...

無論如何,這是我如何做到這一點。我沒有移動應用程序,所以我去flipkart.com並搜索翻蓋,並編寫下面的代碼來演示我在說什麼。這段代碼有效,我只是跑它。

public static void main(String[] args) 
{ 
    WebDriver driver = new FirefoxDriver(); 
    driver.manage().window().maximize(); 
    driver.get("http://www.flipkart.com/search?q=flip+cover&as=on&as-show=on&otracker=start&as-pos=4_q_flip+cover&sid=search.flipkart.com&storePath=search.flipkart.com&type=pr&redirectToResponseURL=false&redirection=true&isMsiteTraffic=1"); 
    List<Product> products = new ArrayList<>(); // List of Product type that will contain each product on the page 
    List<WebElement> productContainers = driver.findElements(By.cssSelector("div.gd-col.gu3")); // the outermost element that contains all data related to a given product 
    // loop through the product container elements and extract each bit of data that we care about 
    for (WebElement productContainer : productContainers) 
    { 
     String name = productContainer.findElement(By.cssSelector("a[data-tracking-id='prd_title']")).getText().trim(); 
     String ratingStars = ""; // we have to initialize these variables at this scope so we can access them later outside the IF below 
     String NoOfRatings = ""; // NOTE: if a rating does not exist for this product, ratingStars and NoOfRatings will be empty string, "" 
     // these next two lines are how we determine if a piece of data exists... get the element using .findElements... 
     List<WebElement> ratingContainer = productContainer.findElements(By.cssSelector("div.pu-rating")); 
     // ... and then check to see if the list is empty 
     if (!ratingContainer.isEmpty()) 
     { 
      // ratings exist for this product, grab the relevant data 
      WebElement rating = ratingContainer.get(0).findElement(By.cssSelector("div.fk-stars-small")); 
      ratingStars = rating.getAttribute("title"); // product rating in stars 
      NoOfRatings = ratingContainer.get(0).getText().trim(); // the total number of ratings, you can parse this string and extract the number, if desired 
     } 
     String finalPrice = productContainer.findElement(By.cssSelector("div.pu-final")).getText().trim(); // the price, you can extract the number, if desired 
     products.add(new Product(name, finalPrice, ratingStars, NoOfRatings)); // add all the relevant data into a nice, neat package just for this one product 
    } 

    // dumps the data for the products on the page 
    for (Product product : products) 
    { 
     System.out.println("Product: " + product.name); 
     System.out.println("Rating: " + product.ratingStars); 
     System.out.println("Number of ratings: " + product.NoOfRatings); 
     System.out.println("Final price: " + product.finalPrice); 
     System.out.println("-----------------------------"); 
    } 
} 

// this class holds just 4 bits of data for each product, you can obviously add more to the class if you want to store more data 
public static class Product 
{ 
    public String name; 
    public String finalPrice; 
    public String ratingStars; 
    public String NoOfRatings; 

    public Product(String name, String finalPrice, String ratingStars, String NoOfRatings) 
    { 
     this.name = name; 
     this.finalPrice = finalPrice; 
     this.ratingStars = ratingStars; 
     this.NoOfRatings = NoOfRatings; 
    } 
} 

輸出類似於

----------------------------- 
Product: KolorEdge Flip Cover for Lenovo A6000 Plus (Black) 
Rating: 3 stars 
Number of ratings: (26 ratings) 
Final price: Rs. 160 
----------------------------- 
Product: Jeelo Flip Cover for Motorola Moto G 2nd Generation (Bl... 
Rating: 3 stars 
Number of ratings: (128 ratings) 
Final price: Rs. 137 
----------------------------- 
...