【问题标题】:How to get Dynamic Xpath of a webtable?如何获取 webtable 的动态 Xpath?
【发布时间】:2018-07-04 08:22:43
【问题描述】:
List<WebElement>table=driver.findElements(By.xpath("//*[@id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr"));
JavascriptExecutor jse = (JavascriptExecutor) driver;
// jse.executeScript("arguments[0].scrollIntoView();",table);
jse.executeScript("arguments[0].style.border='3px solid red'",table);
int row= table.size();

我无法获得所需的行数和列数。我提供的 xpath 没有找到现场表格

链接:Click here

我必须获取手机的规格。

【问题讨论】:

  • 您的目标是“技术细节”部分吗?
  • 是的。只有技术细节@MasterPo

标签: java html selenium


【解决方案1】:

而不是这个 xpath :

//*[@id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr  

使用这个:

//*[@id="prodDetails"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr  

虽然我不建议你使用绝对 xpath。您可以选择更具可读性和简单性的相对 xpath。

相对 Xpath:

//div[@id='prodDetails']/descendant::div[@class='pdTab'][1]/descendant::tbody/tr  

在代码中类似于:

List<WebElement>table=driver.findElements(By.xpath("//div[@id='prodDetails']/descendant::div[@class='pdTab'][1]/descendant::tbody/tr"));

【讨论】:

    【解决方案2】:

    而不是绝对xpath:

    //*[@id=\"prodDetails\"]/div[2]/div[1]/div/div[2]/div/div/table/tbody/tr  
    

    我建议使用简单的相对 xpath:

    //*[@id='prodDetails']//table/tbody/tr  
    

    如果页面中没有其他表,则此 xpath 将起作用。否则,请确保两个表都可以通过某些属性进行区分

    【讨论】:

    • 请注意,此 //*[@id='prodDetails']//table/tbody/tr 将提供 21 个条目,其中 OP xpath 只有 16 个条目。
    • 搜索具有特定 id 或类的“div”之一,这将为您提供特定的表
    • 是的!使用您的 xpath 和 OP xpath 检查一次。有区别。
    • 使用下面的xpath提取表中的行数和列数:
    • //div[@class='section techD']//span[text()='Technical Details']/../..//table/tbody/tr
    【解决方案3】:

    您可以使用以下 Xpath 获取总行数。

    在上面的链接中,我们有多个具有相同类的部分,并且两个表也具有相似的定位器。因此,您需要根据表名获取元素,如下所示

    注意:您可以在不使用JavascriptExecutor 的情况下实现此目的

        WebDriverWait wait=new WebDriverWait(driver,20);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='section techD']//span[text()='Technical Details']/ancestor::div[@class='section techD']//table//tr")));
    
        List<WebElement> rowElementList=driver.findElements(By.xpath("//div[@class='section techD']//span[text()='Technical Details']/ancestor::div[@class='section techD']//table//tr"));
        int row= rowElementList.size();
        System.out.println(row);//16
    

    输出: 16

    假设,如果你想得到一个额外的信息表行详细信息,你可以使用上面的 Xpath 将部分替换为Additional Information

        List<WebElement> additionInfoList=driver.findElements(By.xpath("//div[@class='section techD']//span[text()='Additional Information']/ancestor::div[@class='section techD']//table//tr"));
        System.out.println(additionInfoList.size());//Output: 5
    

    输出: 5

    最后,您可以迭代上面的列表并提取表格内容详细信息

    【讨论】:

    • 我仍然没有得到第 0 行和第 0 列。
    • 能否在查找元素列表之前添加显式等待
    • 用明确的等待条件更新了答案。请立即检查。我收到了预期的回复:)
    【解决方案4】:

    XPATH 可能很难阅读,尤其是当您需要大量使用它时。

    你可以试试univocity-html-parser

        HtmlElement e = HtmlParser.parseTree(new UrlReaderProvider("your_url"));
    
        List<HtmlElement> rows = e.query()
                .match("div").precededBy("div").withExactText("Technical Details")
                .match("tr").getElements();
    
        for(HtmlElement row : rows){
            System.out.println(row.text());
        }
    

    上面的代码会打印出来:

        OS Android
        RAM 2 GB
        Item Weight 150 g
        Product Dimensions 7.2 x 14.2 x 0.9 cm
        Batteries: 1 AA batteries required. (included)
        Item model number G-550FY
        Wireless communication technologies Bluetooth, WiFi Hotspot
        Connectivity technologies GSM, (850/900/1800/1900 MHz), 4G LTE, (2300/2100/1900/1800/850/900 MHz)
        Special features Dual SIM, GPS, Music Player, Video Player, FM Radio, Accelerometer, Proximity sensor, E-mail
        Other camera features 8MP primary & 5MP front
        Form factor Touchscreen Phone
        Weight 150 Grams
        Colour Gold
        Battery Power Rating 2600
        Whats in the box Handset, Travel Adaptor, USB Cable and User Guide
    

    或者,以下代码更有用,因为我相信您可能也希望从该页面获得更多内容,并且获取包含数据的行通常是您最终想要的结果:

        HtmlEntityList entityList = new HtmlEntityList();
        HtmlEntitySettings product = entityList.configureEntity("product");
    
        PartialPath technicalDetailRows = product.newPath()
                .match("div").precededBy("div").withExactText("Technical Details")
                .match("tr");
    
        technicalDetailRows.addField("technical_detail_field").matchFirst("td").classes("label").getText();
        technicalDetailRows.addField("technical_detail_value").matchLast("td").classes("value").getText();
    
        HtmlParserResult results =  new HtmlParser(entityList).parse(new UrlReaderProvider("your_url")).get("product");
    
        System.out.println("-- " + Arrays.toString(results.getHeaders())  + " --");
        for(String[] row : results.getRows()){
            System.out.println(Arrays.toString(row));
        }
    

    现在这会产生:

        OS = Android
        RAM = 2 GB
        Item Weight = 150 g
        Product Dimensions = 7.2 x 14.2 x 0.9 cm
        Batteries: = 1 AA batteries required. (included)
        Item model number = G-550FY
        Wireless communication technologies = Bluetooth, WiFi Hotspot
        Connectivity technologies = GSM, (850/900/1800/1900 MHz), 4G LTE, (2300/2100/1900/1800/850/900 MHz)
        Special features = Dual SIM, GPS, Music Player, Video Player, FM Radio, Accelerometer, Proximity sensor, E-mail
        Other camera features = 8MP primary & 5MP front
        Form factor = Touchscreen Phone
        Weight = 150 Grams
        Colour = Gold
        Battery Power Rating = 2600
        Whats in the box = Handset, Travel Adaptor, USB Cable and User Guide
    

    披露:我是这个库的作者。它是商业封闭源代码,但可以为您节省大量开发时间。

    【讨论】:

      猜你喜欢
      • 2020-07-30
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多