Selenium Java:获取产品浏览量并点击浏览量最高的产品链接
问题:用Selenium Java获取浏览量最高的产品并点击其元素
需求:实现以下操作:获取页面中产品的浏览量,找到浏览量最高的产品,点击其对应的元素。目标网页的HTML结构片段如下:
<section id="135156028" data-scrolled="false" class="AdItem_adOuterHolder__Z29Nf"> <article class="AdItem_adHolder__GL0yo"> <a class="Link_link__J4Qd8 Link_inherit___qXEP" target="_self" id="" rel="" role="button" tabindex="-1" href=".." style="align-items: flex-start;"> <div class="AdItem_imageHolder__DYGd_" style="max-width: 128px; min-width: 128px; height: 120px;"> <img src="..."> </div> </a> <div class="AdItem_descriptionHolder__xnkD4"> <div class="AdItem_adInfoHolder___36KR"></div> <div class="AdItem_price__k0rQn">650 din</div> <div> <div class="AdItem_viewAndFavorite__pjskf"> <div class="AdItem_favoriteHolder__bKBRE"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="asIcon_greyStroke__NU1Xe asIcon_svg__Zm34q"> </svg> <span class="AdItem_count__iNDqG">**144**</span> </div> <div class="AdItem_favoriteHolder__bKBRE"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="asIcon_greyStroke__NU1Xe asIcon_svg__Zm34q"> </svg> <span class="AdItem_count__iNDqG">13</span> </div> </div> <div class="AdItem_postedStatus__C6vfK">...</div> </div> </div> </article> </section>
用户指定使用XPath //div[@class='AdItem_viewAndFavorite__pjskf']//div[1] 获取浏览量,已尝试编写代码获取最高浏览量的产品名称,但无法关联到可点击的元素,代码如下:
@FindBy(xpath = "//div[@class='AdItem_name__BppRQ']") List<WebElement> productsList; @FindBy(xpath = "//div[@class='AdItem_viewAndFavorite__pjskf']//div[1]") List<WebElement> productViewsList; public SingleProductPage chooseHighestViewsProduct(){ String productName; String productViews; int numberOfViews; HashMap<Integer,String> mapFinalProducts = new HashMap<Integer, String>(); for (int i=0;i<productsList.size();i++){ productName = productsList.get(i).getText(); productViews = productViewsList.get(i).getText(); numberOfViews = Integer.parseInt(productViews); mapFinalProducts.put(numberOfViews, productName); } Set<Integer> allKeys = mapFinalProducts.keySet(); ArrayList<Integer> listOfProductValues = new ArrayList<Integer>(allKeys); Collections.sort(listOfProductValues); int highestViews = listOfProductValues.get(listOfProductValues.size()-1); }
核心问题分析
- 原代码使用
HashMap存储浏览量和产品名称,若存在相同浏览量的产品,后加入的会覆盖之前的,导致数据丢失。 - 两个独立的
List<WebElement>分别定位产品名称和浏览量,可能因页面加载顺序、元素渲染延迟导致索引不匹配,无法准确关联产品和对应的元素。
优化思路
直接定位每个产品的外层容器,在容器内部通过相对XPath获取浏览量和对应的元素,确保每个产品的信息一一对应,再遍历找到浏览量最高的产品的元素并点击。
修改后的代码示例
import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import java.util.List; public class ProductListPage { // 定位所有产品的外层容器(每个section对应一个产品) @FindBy(xpath = "//section[@class='AdItem_adOuterHolder__Z29Nf']") List<WebElement> productContainers; public SingleProductPage chooseHighestViewsProduct() { int maxViews = -1; WebElement targetProductLink = null; for (WebElement container : productContainers) { // 在当前产品容器内,获取浏览量文本 WebElement viewCountElement = container.findElement(By.xpath(".//div[@class='AdItem_viewAndFavorite__pjskf']//div[1]/span[@class='AdItem_count__iNDqG']")); String viewText = viewCountElement.getText().trim(); int currentViews = Integer.parseInt(viewText); // 在当前产品容器内,获取对应的<a>元素 WebElement productLink = container.findElement(By.xpath(".//a[@class='Link_link__J4Qd8 Link_inherit___qXEP']")); // 更新最大浏览量和对应的链接 if (currentViews > maxViews) { maxViews = currentViews; targetProductLink = productLink; } } // 点击浏览量最高的产品链接 if (targetProductLink != null) { targetProductLink.click(); return new SingleProductPage(); } else { throw new RuntimeException("未找到任何产品或浏览量数据"); } } }
代码说明
- 定位产品容器:通过
//section[@class='AdItem_adOuterHolder__Z29Nf']获取所有产品的外层容器,保证每个容器包含该产品的所有信息(链接、浏览量等)。 - 相对XPath使用:在循环中,对每个容器使用
.//开头的相对XPath,只在当前容器内查找元素,避免全局查找导致的索引错位。 - 记录目标元素:遍历过程中直接比较浏览量,记录最大浏览量对应的元素,最后直接点击该元素,无需额外关联步骤。
- 异常处理:加入空判断,避免因页面无产品导致的空指针异常。
内容的提问来源于stack exchange,提问作者Stefan Itic
相关产品推荐
相关产品推荐

