使用 Java Selenium 精准点击 Google 搜索结果与导航

使用 java selenium 精准点击 google 搜索结果与导航

本教程详细介绍了如何使用 Java Selenium WebDriver 自动化 Google 索过程,包括处理 Cookie 同意弹窗、输入搜索关键词、提交搜索请求,以及从搜索结果中准确识别并点击目标链接。文章通过一个完整的代码示例,演示了如何利用不同的元素定位策略(如 ID、Name、Class Name、Tag Name)来有效与网页元素交互,并提供了关键步骤的解析与注意事项,旨在帮助开发者掌握自动化网页导航的核心技能。

引言

在使用 Java Selenium 进行网页自动化测试或数据抓取时,经常会遇到需要与动态网页元素交互的场景,例如在搜索引擎中输入关键词并点击搜索结果。本文将专注于解决一个常见问题:如何在使用 Java Selenium 成功执行 Google 搜索后,准确地点击搜索结果列表中的特定链接。我们将通过一个具体的案例,详细讲解实现这一目标的步骤和技巧。

环境准备

在开始之前,请确保您的开发环境中已配置好以下组件:

Java Development Kit (JDK):版本 8 或更高。Maven 或 Gradle:用于项目管理和依赖引入。Selenium WebDriver 库:在 pom.xml (Maven) 或 build.gradle (Gradle) 中添加 Selenium 依赖。ChromeDriver:与您安装的 Chrome 浏览器版本兼容的 ChromeDriver 可执行文件。您可以从 ChromeDriver 官方网站 下载。为了简化驱动管理,强烈推荐使用 WebDriverManager 库,它能自动下载并配置所需的浏览器驱动。

Maven 依赖示例:

立即学习“Java免费学习笔记(深入)”;

                org.seleniumhq.selenium        selenium-java        4.1.2                     io.github.bonigarcia        webdrivermanager        5.3.0     

核心步骤解析

我们将通过以下步骤实现 Google 搜索结果的点击:

1. 初始化 WebDriver

首先,需要初始化 WebDriver 实例,这里我们使用 ChromeDriver。如果使用 WebDriverManager,则无需手动设置 webdriver.chrome.driver 系统属性。

import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import io.github.bonigarcia.wdm.WebDriverManager; // 如果使用 WebDriverManager// ...public static void main(String[] args) {    // 使用 WebDriverManager 自动设置 ChromeDriver    WebDriverManager.chromedriver().setup();    // 或者手动设置 ChromeDriver 路径    // System.setProperty("webdriver.chrome.driver", "path/to/your/chromedriver.exe");    WebDriver driver = new ChromeDriver();    driver.manage().window().maximize(); // 最大化浏览器窗口以确保元素可见    // ...}

2. 导航至 Google 并处理 Cookie 同意弹窗

许多网站(包括 Google)在首次访问时会显示 Cookie 同意弹窗。在进行后续操作前,必须处理这些弹窗。

driver.get("https://www.google.cz"); // 导航到 Google 网站// 尝试接受 Cookie 弹窗。注意:Google 的 Cookie 弹窗元素 ID 或结构可能随时间变化。// L2AGLb 是一个常见的同意按钮 IDList acceptBtns = driver.findElements(By.id("L2AGLb"));if (!acceptBtns.isEmpty() && acceptBtns.get(0).isDisplayed()) {    acceptBtns.get(0).click();} else {    // 如果没有找到特定 ID 的按钮,可以尝试查找包含 "Accept all" 或 "我同意" 文本的按钮    List potentialAcceptButtons = driver.findElements(By.xpath("//button[contains(.,'Accept all') or contains(.,'我同意')]"));    if (!potentialAcceptButtons.isEmpty() && potentialAcceptButtons.get(0).isDisplayed()) {        potentialAcceptButtons.get(0).click();    }}

注意事项: Cookie 同意弹窗的元素定位器(ID、XPath 等)可能会随着网站更新而改变。在实际应用中,您可能需要根据最新的网页结构进行调整。

3. 输入搜索关键词

定位到 Google 搜索框,并使用 sendKeys() 方法输入搜索关键词。

WebElement searchInput = driver.findElement(By.name("q")); // 'q' 是 Google 搜索框的 name 属性searchInput.sendKeys(mySearchString); // mySearchString 是您要搜索的字符串

4. 提交搜索请求

Google 搜索页面通常有多个同名的提交按钮。我们需要找到并点击可见的那个。

List searchBtns = driver.findElements(By.name("btnK")); // 'btnK' 是 Google 搜索按钮的 name 属性for (WebElement searchBtn : searchBtns) {    // 通过判断元素位置和可见性来确定正确的搜索按钮    Point p = searchBtn.getLocation();    if (p.getX() > 0 && p.getY() > 0 && searchBtn.isDisplayed()) {        searchBtn.click();        break;    }}

这里使用 getLocation() 检查元素在页面上的坐标,结合 isDisplayed() 确保元素可见,从而排除隐藏的或不在视口内的同名按钮。

5. 定位并点击搜索结果

搜索结果通常包含在一个特定的 HTML 结构中。我们需要识别这些结构,然后从中提取出实际的链接元素。

纳米搜索 纳米搜索

纳米搜索:360推出的新一代AI搜索引擎

纳米搜索 30 查看详情 纳米搜索

List resultLinks = new ArrayList();// 定位所有包含搜索结果的 div 元素// 'yuRUbf' 是 Google 搜索结果条目常用的 class nameList searchResultDivs = driver.findElements(By.className("yuRUbf"));if (!searchResultDivs.isEmpty()) {    for (WebElement searchResultDiv : searchResultDivs) {        // 在每个结果 div 中找到第一个  标签,即实际的链接        resultLinks.add(searchResultDiv.findElement(By.tagName("a")));    }    // 点击第一个搜索结果链接    if (!resultLinks.isEmpty()) {        resultLinks.get(0).click(); // 点击列表中的第一个链接        // 页面已切换,打印当前 URL 和标题进行验证        System.out.println("Current URL: " + driver.getCurrentUrl());        System.out.println("Current title: " + driver.getTitle());    } else {        System.out.println("未找到任何搜索结果链接。");    }} else {    System.out.println("未找到任何搜索结果容器。");}

这里利用 By.className(“yuRUbf”) 找到每个搜索结果的容器,然后使用 findElement(By.tagName(“a”)) 在该容器内部进一步定位到实际的超链接。这种组合定位方式比直接使用复杂的 XPath 更具鲁棒性。

6. 关闭浏览器

完成所有操作后,务必关闭浏览器实例以释放资源。

driver.quit();

完整示例代码

下面是整合上述所有步骤的完整 Java Selenium 代码示例:

package com.example.selenium;import io.github.bonigarcia.wdm.WebDriverManager;import org.openqa.selenium.By;import org.openqa.selenium.Point;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit; // 用于隐式等待,可选public class GoogleSearchClickTutorial {    public static void main(String[] args) {        // 1. 初始化 WebDriver        WebDriverManager.chromedriver().setup(); // 自动下载并配置 ChromeDriver        WebDriver driver = new ChromeDriver();        driver.manage().window().maximize(); // 最大化浏览器窗口        // driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // 设置隐式等待,可选        List resultLinks = new ArrayList();        String mySearchString = "fantomas wiki"; // 定义搜索关键词        try {            // 2. 导航至 Google 并处理 Cookie 同意弹窗            driver.get("https://www.google.cz");            // 尝试接受 Cookie 弹窗            // 注意:Google 的 Cookie 弹窗元素 ID 或结构可能随时间变化            List acceptBtns = driver.findElements(By.id("L2AGLb"));            if (!acceptBtns.isEmpty() && acceptBtns.get(0).isDisplayed()) {                System.out.println("找到并点击了 Cookie 同意按钮。");                acceptBtns.get(0).click();            } else {                // 备用方案:查找包含特定文本的按钮                List potentialAcceptButtons = driver.findElements(By.xpath("//button[contains(.,'Accept all') or contains(.,'我同意') or contains(.,'全部接受')]"));                if (!potentialAcceptButtons.isEmpty() && potentialAcceptButtons.get(0).isDisplayed()) {                    System.out.println("找到并点击了备用 Cookie 同意按钮。");                    potentialAcceptButtons.get(0).click();                } else {                    System.out.println("未找到 Cookie 同意按钮或其不可见,尝试继续。");                }            }            // 3. 输入搜索关键词            WebElement searchInput = driver.findElement(By.name("q"));            searchInput.sendKeys(mySearchString);            System.out.println("已输入搜索关键词: " + mySearchString);            // 4. 提交搜索请求            List searchBtns = driver.findElements(By.name("btnK"));            boolean clickedSearchButton = false;            for (WebElement searchBtn : searchBtns) {                Point p = searchBtn.getLocation();                if (p.getX() > 0 && p.getY() > 0 && searchBtn.isDisplayed()) {                    searchBtn.click();                    clickedSearchButton = true;                    System.out.println("已点击搜索按钮。");                    break;                }            }            if (!clickedSearchButton) {                System.out.println("未找到可见的搜索按钮。");            }            // 5. 定位并点击搜索结果            // 等待搜索结果加载,这里可以考虑使用显式等待            // new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.visibilityOfElementLocated(By.className("yuRUbf")));            List searchResultDivs = driver.findElements(By.className("yuRUbf"));            if (!searchResultDivs.isEmpty()) {                System.out.println("找到 " + searchResultDivs.size() + " 个搜索结果容器。");                for (WebElement searchResultDiv : searchResultDivs) {                    // 获取 div 中的第一个  标签                    resultLinks.add(searchResultDiv.findElement(By.tagName("a")));                }                // 点击第一个搜索结果链接                if (!resultLinks.isEmpty()) {                    resultLinks.get(0).click();                    System.out.println("已点击第一个搜索结果链接。");                    // 页面已切换,打印当前 URL 和标题进行验证                    System.out.println("当前 URL: " + driver.getCurrentUrl());                    System.out.println("当前标题: " + driver.getTitle());                } else {                    System.out.println("未找到任何搜索结果链接。");                }            } else {                System.out.println("未找到任何搜索结果容器。");            }        } catch (Exception e) {            System.err.println("发生错误: " + e.getMessage());            e.printStackTrace();        } finally {            // 6. 关闭浏览器            if (driver != null) {                driver.quit();                System.out.println("浏览器已关闭。");            }        }    }}

示例输出:

Starting ChromeDriver 107.0.5304.62 (1eec40d3a5764881c92085aaee66d25075c159aa-refs/branch-heads/5304@{#942}) on port 20110Only local connections are allowed.Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.ChromeDriver was started successfully.Lis 29, 2022 11:10:07 DOP. org.openqa.selenium.remote.ProtocolHandshake createSessionINFO: Detected dialect: W3C找到并点击了 Cookie 同意按钮。已输入搜索关键词: fantomas wiki已点击搜索按钮。找到 10 个搜索结果容器。已点击第一个搜索结果链接。当前 URL: https://cs.wikipedia.org/wiki/Fantomas当前标题: Fantomas – Wikipedie浏览器已关闭。

(注:实际输出中的日期和 ChromeDriver 版本信息可能因您的环境和时间而异。)

注意事项与总结

元素定位策略选择: 优先使用 ID、Name、Class Name 进行定位,它们通常比 XPath 更稳定高效。当这些定位器不可用时,再考虑使用 CSS Selector 或 XPath。避免使用过于复杂的 XPath,因为它们对页面结构变化非常敏感。

动态元素和等待机制: 网页元素加载是异步的,尤其在处理弹窗或 AJAX 请求时。本示例中虽然没有显式使用等待,但在实际项目中,强烈建议使用 WebDriverWait 结合 ExpectedConditions 来等待元素出现或可点击,以提高脚本的稳定性。例如:

import org.openqa.selenium.support.ui.WebDriverWait;import org.openqa.selenium.support.ui.ExpectedConditions;import java.time.Duration; // Java 8+// ...WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("someId")));element.click();

页面结构变化: Google 等大型网站的 UI 结构可能会频繁更新。这意味着您编写的定位器(如 By.id(“L2AGLb”) 或 By.className(“yuRUbf”))可能在未来某个时间点失效。定期检查并更新定位器是维护自动化脚本的必要工作。

错误处理: 在自动化脚本中加入 try-catch-finally 块是一个好习惯,可以捕获潜在的 NoSuchElementException 或其他运行时错误,并确保在脚本执行完毕(无论成功与否)都能正确关闭浏览器。

浏览器最大化: driver.manage().window().maximize() 有助于确保所有元素都在可视区域内,减少因元素不在视口内而导致的点击失败问题。

通过本文的详细教程和示例代码,您应该已经掌握了使用 Java Selenium 自动化 Google 搜索并点击搜索结果的关键技术。理解并灵活运用各种元素定位策略,结合适当的等待机制和错误处理,将使您的自动化脚本更加健壮和可靠。

以上就是使用 Java Selenium 精准点击 Google 搜索结果与导航的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/578272.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月10日 09:29:00
下一篇 2025年11月10日 09:30:04

相关推荐

  • CakePHP:限制 hasMany 查询中关联表和主表的字段

    本文档旨在解决在使用 CakePHP 的 hasMany 关联查询时,如何限制主表和关联表中返回的字段,以优化性能。我们将探讨如何在查询中使用 select() 方法来指定需要的字段,并解决因缺少主键导致关联数据无法正确合并的问题。同时,介绍如何使用结果格式化器来移除不需要的字段。 使用 selec…

    2025年12月11日
    000
  • PHP 致命错误:参数类型不匹配问题排查与解决

    在 PHP 开发中,”Catchable Fatal Error: Argument 1 passed to … must be an instance of …” 错误通常表示函数或方法的参数类型不符合预期,即传递的参数不是期望的类实例。这通常是由于…

    2025年12月11日
    000
  • 将 PHP POST 请求转换为 C

    本文旨在帮助开发者将 PHP 中处理 application/x-www-form-urlencoded 格式的 POST 请求转换为 C# 代码,解决常见的 415 Unsupported Media Type 错误。我们将重点介绍如何在 C# 中正确设置 Content-Type 请求头,并提供…

    2025年12月11日
    000
  • 将 PHP POST 请求转换为 C# 实现

    本文旨在帮助开发者将 PHP 中接收 application/x-www-form-urlencoded 数据的 POST 请求转换为 C# .NET Core 中的等效实现。我们将探讨如何正确设置 Content-Type 头部,以及如何在 C# 中接收和处理来自第三方 API 的数据,从而避免 …

    2025年12月11日
    000
  • PHP POST 请求 REST API:混合数组和对象的正确处理方式

    本文旨在解决在使用 PHP 向 REST API 发送 POST 请求时,遇到的混合数组和对象结构处理问题。通过分析常见的错误配置,提供正确的 PHP 代码示例,确保 addresses 字段中的 billing 数据以 API 期望的数组形式发送,从而避免因数据格式验证失败导致的请求错误。文章包含…

    2025年12月11日
    000
  • 使用 PHP 构建符合 REST API 要求的复杂 JSON 数据

    本文档旨在帮助开发者解决在使用 PHP 向 REST API 发送 POST 请求时,构建包含混合数组和对象的复杂 JSON 数据结构的问题。我们将重点关注如何正确格式化数据,特别是嵌套数组和对象,以满足 API 的验证要求。通过示例代码和详细解释,你将学会如何避免常见的”missing…

    2025年12月11日
    000
  • PHP 使用 POST 方法向 REST API 传输混合数组和对象数据

    本文档旨在解决在使用 PHP 的 POST 方法向 REST API 传输包含混合数组和对象的数据时,由于数据结构不匹配导致 API 验证失败的问题。通过对比 Postman 中成功请求的 JSON 结构,分析 PHP 代码生成的数据结构差异,并提供修改方案,确保 PHP 代码能够生成符合 API …

    2025年12月11日
    000
  • PHP NumberFormatter:解决货币格式化后字符串比较失败的问题

    在使用 PHP 的 NumberFormatter 类进行货币格式化时,开发者可能会遇到一个看似奇怪的问题:明明两个字符串在视觉上完全一样,但使用 == 运算符进行比较时却返回 false。本文将深入探讨这个问题,并提供解决方案。 问题分析 正如摘要所提到的,问题通常出在格式化后的字符串中包含了不可…

    2025年12月11日
    000
  • Laravel 控制器中类型提示的解析方法

    在 Laravel 框架中,类型提示是一种强大的特性,它允许我们在控制器的方法参数中声明期望的类型。当控制器方法被调用时,Laravel 的服务容器会自动解析这些类型提示,并将相应的对象注入到方法中。对于路由参数,特别是需要直接注入模型实例的情况,Laravel 提供了路由模型绑定机制。 路由模型绑…

    2025年12月11日
    000
  • Laravel 8 中验证序列化表单数据

    本文旨在解决 Laravel 8 中验证通过 serialize() 方法从前端传递过来的表单数据的问题。重点讲解如何正确地使用 Laravel 的验证器来处理此类数据,包括创建验证器实例、执行验证以及处理验证错误,并提供示例代码,帮助开发者更好地理解和应用。 当从前端通过 serialize() …

    2025年12月11日
    000
  • 使用 Laravel 8 验证序列化表单数据

    本文旨在解决 Laravel 8 中验证序列化表单数据的问题。通过 parse_str 函数将序列化的字符串转换为数组后,需要使用 Laravel 的验证器进行数据验证。本文将提供一个详细的示例,展示如何正确地使用 Validator facade 创建验证器实例,并处理验证结果,从而确保数据的有效…

    2025年12月11日
    000
  • 居家创业 PHP加Stable Diffusion搭建AI商品展示页

    居家创业者可通过PHP与Stable Diffusion协同构建AI商品图生成系统,实现低成本、高效率的个性化电商视觉内容生产。核心流程为:前端收集产品信息 → PHP后端构造提示词并调用Stable Diffusion API → 生成Base64图片数据 → 解码保存并返回链接 → 前端展示。关…

    2025年12月11日 好文分享
    000
  • 为电商产品添加不同类型图片:Laravel 实现方案

    本文针对电商网站中为不同产品类型添加特定图片的需求,提供了一种基于 Laravel 的解决方案。通过将产品和图片信息分开处理,并引入 image-picker jQuery 插件,实现了灵活的产品图片管理。文章将详细介绍产品创建和图片关联的实现步骤,并提供相应的代码示例,帮助开发者构建更完善的电商平…

    2025年12月11日
    000
  • 为电商产品类型添加不同图片:Laravel 解决方案

    摘要 本文档提供了一个在 Laravel 电商平台中,为不同产品类型关联不同图片的方法。通过将产品创建和图片关联拆分为两个步骤,并利用 jQuery 插件 image-picker,简化了用户操作,并解决了在单个表单中处理复杂图片上传和关联的问题。最终,将图片 ID 存储在产品变体表中,方便后续查询…

    2025年12月11日
    000
  • 为电商网站产品类型添加不同图片:Laravel 实现方案

    本文档旨在提供一种在 Laravel 电商网站中,为不同产品类型(Product Variations)关联不同图片的方法。通过将产品图片上传与产品类型信息录入分离,并利用中间页面选择图片,最终将图片ID与产品类型关联,从而实现灵活的产品展示。本教程将详细介绍实现步骤,并提供关键代码示例。 方案概述…

    2025年12月11日
    000
  • 输出格式要求:PHP获取目录文件列表并在JavaScript中使用

    本文介绍如何使用PHP读取指定目录下的所有文件名,并将这些文件名传递到JavaScript中进行使用。通过PHP的opendir、readdir等函数获取文件列表,然后使用json_encode将PHP数组转换为JSON字符串,最后在JavaScript中解析该JSON字符串,从而获得文件列表。 P…

    2025年12月11日
    000
  • PHP中JSON文件缓存与客户端刷新策略

    本文深入探讨了PHP应用中JSON文件在客户端浏览器上的缓存问题及其解决方案。当本地JSON数据更新时,客户端浏览器可能因缓存机制而无法获取最新数据,导致用户需要手动清除缓存。文章详细介绍了如何利用PHP的filemtime函数生成动态版本化URL,实现高效的缓存失效(Cache Busting),…

    2025年12月11日
    000
  • 手把手教你用PHP和ChatGPT生成个性化简历网站

    用PHP和ChatGPT打造个性化简历网站,首先准备PHP环境、编辑器及OpenAI API Key;创建项目结构并配置API;封装ChatGPT接口函数;通过清晰指令生成自我介绍、技能列表等内容;结合CSS美化页面;利用ChatGPT获取设计建议实现风格独特;优化Prompt、验证内容准确性并人工…

    2025年12月11日 好文分享
    000
  • 告别无聊 PHP加MidJourney生成动态艺术画廊

    答案:通过PHP与MidJourney间接交互,构建自动化动态艺术画廊。PHP作为后端指挥官,借助HTTP客户端(如Guzzle)向Discord机器人发送/imagine指令,触发MidJourney生成图像;利用任务队列与轮询或Webhook机制获取生成结果,再通过PHP下载图片并存储至数据库(…

    2025年12月11日
    000
  • 用PHP和Bard做个天气机器人 每天微信推送提醒

    答案:使用PHP调用天气API获取数据,通过Google AI Gemini生成个性化文案,再经%ignore_a_1%公众号或企业微信推送,结合定时任务实现每日自动推送。 用PHP和Bard来搭建一个每天微信推送的天气机器人,这听起来是完全可行的,而且能玩出不少花样。核心思路就是:PHP负责数据获…

    2025年12月11日 好文分享
    000

发表回复

登录后才能评论
关注微信