干货|Selenium,从入门实战
创始人
2024-05-30 21:05:07
0

工作中的需求是多种多样,是否有遇到过这样的需求:一个H5表单,用户通过多渠道入单,期望帮用户的下单请求提交至这个H5上。

这种通常就是在二级服务商、代理服务商的服务商会遇到这样的需求,源头供应商没有接口的能力,提供到一个页面,支持提交表单数据。

这种场景,我们可以怎样提交呢?

  • 纯人工肯定没毛病,收集到用户信息后,替用户向上游提交下单请求。可是量大就不现实了。
  • 最终肯定还是期望自动化,既保障用户隐私又提升效率,这也是智能化的趋势。

那我们可以想到的就是一些辅助自动化的工具,模拟人的动作,又不需要人来干预,其中有Selenium、Appnium。这些原理都类似,利用自动化测试的思想,来模拟进行表单提交。

以上案例是基于H5网页的,那么使用Selenium是再合适不过了。
请注意,以上Selenium是在多方认同恰当的业务流程中,进行模拟填单提交的自动化操作,不可用于不合规的牟利,目前非加白合规的流程也都会有反爬虫的措施来抵御使用Selenium自动化的操作。

  • 一、从0入门Selenium
    • 1.1 打开URL
    • 1.2 获取页面标题
    • 1.3 配置超时等待策略
    • 1.4 查找页面元素
    • 1.5 操作页面元素
  • 二、使用案例
    • 2.1 明确本地版本
    • 2.2 下载指定驱动
    • 2.3 加载驱动的几种方法
    • 2.4 Java 引入依赖
    • 2.5 撰写代码

一、从0入门Selenium

python有丰富的类库,与Selenium结合紧密,由于本人相对熟悉JAVA,以下样例主要通过java进行实现。

Selenium官方Github:https://github.com/SeleniumHQ/seleniumhq.github.io

以下先介绍一些基本操作:

1.1 打开URL

ChromeOptions、ChromeDriver的详细参数可参看官网:

ChromeOptions option = new ChromeOptions();
WebDriver driver = new ChromeDriver();
driver.get("https://www.selenium.dev/selenium/web/web-form.html");

1.2 获取页面标题

String title = driver.getTitle();

1.3 配置超时等待策略

有时候页面加载需要的时间不确定,为了确保接下来获取页面元素的步骤没有问题,通常会配置一个等待时间,让页面元素有足够的时间渲染,避免脚本的异常

 driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

1.4 查找页面元素

在使用API的时候会发现,有几种可以获取页面元素的方法,具体参照实际情况

源码中By的方法有:

    public static By id(String id) {return new By.ById(id);}public static By linkText(String linkText) {return new By.ByLinkText(linkText);}public static By partialLinkText(String partialLinkText) {return new By.ByPartialLinkText(partialLinkText);}public static By name(String name) {return new By.ByName(name);}public static By tagName(String tagName) {return new By.ByTagName(tagName);}public static By xpath(String xpathExpression) {return new By.ByXPath(xpathExpression);}public static By className(String className) {return new By.ByClassName(className);}public static By cssSelector(String cssSelector) {return new By.ByCssSelector(cssSelector);}
  • 1.4.1 根据ClassName获取元素

一个页面,在特殊或者关键的DIV上,规范非低代码的平台上都会有特殊class标识,可能要定义操作或者样式

可以通过以下方法获取上面这个div

WebElement vegetable = driver.findElement(By.className("code-toolbar"));
  • 1.4.2 根据ID获取获取页面元素

和ClassName类似,当一个页面元素没有一个单独定位的class属性,那么可以看一下是否有ID属性

    以上这个class经观察,有但不是唯一标识,我想唯一获取这个元素,那么看到ID是一个唯一的属性,那么就可以通过ID获取

    WebElement fruits = driver.findElement(By.id("tabs-1"));
    
    • 1.4.3 根据name获取页面元素

    name和ID、ClassName,如果具有特殊性可以唯一标识,那也很好用的

    WebElement fruits = driver.findElement(By.name("tabsname"));
    
    • 1.4.4 根据TagName获取页面元素

    有一种需要获取下拉框内的全部元素内容,或者页面的一个input框元素,可以使用TagName

    List elements = driver.findElements(By.tagName("li"));for (WebElement element : elements) {System.out.println("text:" + element.getText());
    }
    
    • 1.4.5 根据CSS标识获取元素

    有时候页面元素存在嵌套,不希望通过ID或者ClassName层层获取,为了更加高效,可是使用CSS选择器或XPath选择器,来定位页面元素
    css选择器中针对ID和ClassName存在简写

    • #表示id属性定位器,后面紧跟id属性值
    • 英文的. 表示class定位器,后面紧跟class属性值
    • 子代选择器用>表示,这个是直接隶属的关系
    • 毗邻元素选择器用+表示

    这边CSS的组合写法和XPath的写法相对复杂一些,后面单独列一期

    • 1.4.6 获取某元素的子元素
    WebElement element = driver.findElement(By.tagName("div"));
    // 获取这个div下面的全部的p标签内容
    List elements = element.findElements(By.tagName("p"));
    for (WebElement e : elements) {System.out.println(e.getText());
    }
    

    1.5 操作页面元素

    • 1.5.1 输入框设置内容

    比如我们定位了百度输入框,需要在输入框中写入内容。表单且是text类型输入框的可以填入,如果是不可编辑的则无法定位修改该元素。

    driver.findElement(By.name("q")).sendKeys("q" + Keys.ENTER);
    写了一个q并且键入一个ENTER
    
    • 1.5.2 输入清空

    一个可清空、可编辑的表单文本输入框,可以选中后进行清空。

    WebElement searchInput = driver.findElement(By.name("q"));
    searchInput.sendKeys("selenium");
    searchInput.clear();
    
    • 1.5.3 表单提交

    Selenium4开始将不再实现

    • 1.5.4 元素点击

    通常提交表单都有标识性的按钮实现,所以也可以定位点击提交按钮来实现表单的提交

    WebElement agreeCheck = driver.findElement(By.id("agree"));
    agreeCheck.click();
    
    • 1.5.5 下拉选择

    需要是Select选择框可以进行以下操作,有些下拉框是原生的ul\li的,不可使用

    
    
    WebElement selectElement = driver.findElement(By.name("selectomatic"));
    Select select = new Select(selectElement);
    List optionList = select.getOptions();//单选
    List selectedOptionList = select.getAllSelectedOptions();//多选
    

    这种情况,我们通常想操控这个下拉框选择某一个元素,可以通过以下方式选择,如果某一个元素被禁用了,就不可被选中。

    //根据文本选择
    select.selectByVisibleText("Four");
    //根据值选择
    select.selectByValue("two");
    //根据排序选择
    select.selectByIndex(3);
    
    • 1.5.6 屏幕滚动

    有时候点开的页面需要通过滚动的方式,让页面元素能够展示并且获取。

    //定位一个页面元素,让它滚动到视线内
    WebElement element = driver.findElement(By.className("btnPay"));
    driver.executeScript("arguments[0].scrollIntoView();", element);//指定滚动一定像素
    String js="var q=document.documentElement.scrollTop=10000";
    driver.executeScript(js);
    

    此外还有很多的操作场景,比如自动化文件上传下载、模拟鼠标操作、模拟键盘输入、滚轮滚动、页面截图等等

    具体可以参看官方文档:https://www.selenium.dev/documentation/webdriver/getting_started/

    官方也是极力推荐大家往Selenium4上面迁移,会带来一些改变,但会有更多的操作特性

    二、使用案例

    以下通过一个实例,来介绍使用Selenium的一些细节。

    2.1 明确本地版本

    需要保证浏览器(具体是Chrome/Chromium, Firefox, Internet Explorer, Edge, and Safari. 它是都能支持的,具体看自己情况)

    比如我本地是Chrome,那我首先确认我的chrome版本

    打开浏览器,输入:chrome://version,就能看到了

    Google Chrome	110.0.5481.177 (正式版本) (x86_64) 
    修订版本	f34f7ab2d4ca4ad498ef42aeba4f4eb2c1392d63-refs/branch-heads/5481@{#1239}
    

    2.2 下载指定驱动

    如果本地能够找到chrome驱动的可以直接使用,此外还可以根据目前自己的版本去官方下载:https://chromedriver.chromium.org/downloads

    比如我已经明确自己是110版本,那么根据指引:If you are using Chrome version 110, please download ChromeDriver 110.0.5481.77

    2.3 加载驱动的几种方法

    • 2.3.1 Selenium v4.6 使用Selenium Manager

    • 2.3.2 Driver Management Software

    WebDriverManager.chromedriver().setup();
    WebDriver driver = new ChromeDriver();
    
    • 2.3.3 通过本地环境配置chromedriver
    echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
    source ~/.bash_profile
    
    • 2.3.4 通过写死驱动的路径
    System.setProperty("webdriver.chrome.driver","/path/to/chromedriver");
    ChromeDriver driver = new ChromeDriver();
    

    2.4 Java 引入依赖

    具体取决于各个环节的版本

            org.seleniumhq.seleniumselenium-java4.8.0
    

    2.5 撰写代码

       public static void main(String[] args) {System.setProperty("webdriver.chrome.driver","/Users/chenzy/Downloads/chromedriver");ChromeOptions option = new ChromeOptions();option.addArguments("--start-maximized");ChromeDriver driver = new ChromeDriver(option);driver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);try {driver.get("https://www.baidu.com/");WebElement payCode = driver.findElement(By.id("lg"));int x = payCode.getLocation().x;int y = payCode.getLocation().y;// Get entire page screenshotFile screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);BufferedImage fullImg = ImageIO.read(screenshot);// Get the location of element on the pagePoint point = payCode.getLocation();// Get width and height of the elementint eleWidth = payCode.getSize().getWidth();int eleHeight = payCode.getSize().getHeight();// Crop the entire page screenshot to get only element screenshotBufferedImage eleScreenshot = fullImg.getSubimage(point.getX(), point.getY(),eleWidth, eleHeight);ImageIO.write(eleScreenshot, "png", screenshot);// Copy the element screenshot to diskFile screenshotLocation = new File("~/Downloads/GoogleLogo_screenshot.png");FileUtils.copyFile(screenshot, screenshotLocation);} catch (Exception e) {e.printStackTrace();}}
    

    相关内容

    热门资讯

    【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
    银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
    不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
    AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
    Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
    北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
    AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
    AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
    ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
    月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...