-1

Please visit link : https://www.cricbuzz.com/live-cricket-scorecard/22408/kxip-vs-dc-13th-match-indian-premier-league-2019

Here I want to print runs scored by individual player from table "Delhi Capitals Innings". I want to restrict the scope to table first and from then use method findElemets to get desired output. I am using below code.

If replace

System.out.println(table.findElements(By.xpath("//div[@class='cb-col cb-col-8 text-right text-bold']")).get(i).getText());

with

System.out.println(table.findElements(By.xpath("//div[@id='innings_2']//div[@class='cb-col cb-col-100 cb-ltst-wgt-hdr'] //div[@class='cb-col cb-col-8 text-right text-bold']")).get(i).getText());

will get correct result. But I want to do it by limiting the scope of driver.

public class Runs{
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        System.setProperty("webdriver.chrome.driver","C:\\ChromeDriver\\1\\chromedriver.exe");

        WebDriver driver = new ChromeDriver();
        driver.get("https://www.cricbuzz.com/live-cricket-scorecard/22408/kxip-vs-dc-13th-match-indian-premier-league-2019");
        driver.manage().window().maximize();

        WebElement table = driver.findElement(By.xpath("//div[@id='innings_2']//div[@class='cb-col cb-col-100 cb-ltst-wgt-hdr']"));

        int rowCount = table.findElements(By.xpath("//div[@class='cb-col cb-col-8 text-right text-bold']")).size();
        for(int i=0;i<rowCount;i++) {
            System.out.println(table.findElements(By.xpath("//div[@class='cb-col cb-col-8 text-right text-bold']")).get(i).getText());
        }
    }
}

I am getting below output:

R
15
20
6
39
43
29
1
3
1
0
0
2
3
0
2
0
0
R
0
30
28
39
38
0
2
0
0
4
0
2
4
2
1
0
0

It is printing all the elements matching the provided xpath in entire web page. It should print only one present under table "Delhi Capitals Innings". What I am missing in this ?

Sers
  • 12,047
  • 2
  • 12
  • 31
rushikesh
  • 51
  • 1
  • 5

3 Answers3

0

Change the method findelements to findelement in the for loop.

System.out.println(table.findElement(By.xpath("//div[@class='cb-col cb-col-8 text-right text-bold']")).get(i).getText());
supputuri
  • 13,644
  • 2
  • 21
  • 39
0

There're 2 tables with selector you're using. If you want select only first one use below, [1] added to the end:

WebElement table = driver.findElement(By.xpath("//div[@id='innings_2']//div[@class='cb-col cb-col-100 cb-ltst-wgt-hdr'][1]"));

You can get tables by label, below get rows for "Delhi Capitals Innings" table:

//span[.='Delhi Capitals Innings']/ancestor::div[contains(@class,'cb-ltst-wgt-hdr')]/div[.//a[@class='cb-text-link']]

Code:

String tableName = "Delhi Capitals Innings";
List<WebElement> rows = driver.findElement(By.xpath("//span[.='" 
+ tableName + "']/ancestor::div[contains(@class,'cb-ltst-wgt-hdr')]/div[.//a[@class='cb-text-link']]"));
Sers
  • 12,047
  • 2
  • 12
  • 31
0

You are on the right path but there is an issue. Generally what you are trying to do is doable. The part you are missing is in the second XPath. A simple HTML TABLE example.

<table>
    <tr>
        <td></td>
        <td></td>
    </tr>
</table>

To find the TABLE using XPath, you would use //table. To find a cell in the table using a second locator, you would need to add a . to the start of the XPath, e.g. ./tr/td. This tells XPath to start at the relative position. For more info see this question. The code would be something like

WebElement table = driver.findElement(By.xpath("//table"));
WebElement cell = table.findElement(By.xpath("./tr/td"));
                  ^ I'm starting with the table variable here, like you did
                                              ^ but I added the . to indicate relative

Having said all of that, it won't work here. There is no single HTML element that encompases all of the "Delhi Capitals Innings" content. There are actually 4 DIVs inside of the parent DIV that hold all the content.

<div id="innings_2" class="ng-scope">
    <div class="cb-col cb-col-100 cb-ltst-wgt-hdr"></div>
    <div class="cb-col cb-col-100 cb-scrd-sub-hdr cb-bg-gray text-bold">Fall of Wickets</div>
    <div class="cb-col cb-col-100 cb-col-rt cb-font-13">...</div>
    <div class="cb-col cb-col-100 cb-ltst-wgt-hdr"></div>
</div>

You will have to scrape each one separately.

JeffC
  • 22,180
  • 5
  • 32
  • 55
  • Is there a similar logic for CSS ? I want to use CSS instead of Xpath. – rushikesh Apr 04 '19 at 07:28
  • @rushikesh Yes, using my `TABLE` example... for the first locator you can use `By.tagName("table")` or `By.cssSelector("table")` and then for the second locator you can use `By.cssSelector("tr td")` or something like that. There is no equivalent `.` notation in CSS selectors like there is in XPath when searching from an element. – JeffC Apr 04 '19 at 13:13