Selenium+java+maven

目录

Maven项目构建

引入selenium框架

基本元素定位:

元素操作API

WebDriver相关API

三大等待

特殊元素定位与操作


Selenium家族

selenium包括:Selenium IDE、web Driver、Selenium Grid

Selenium IDE:是FireFox的扩展插件,支持用户录制和回放测试

Selenium Driver:提供了各种语言环境的API来支持更多控制权和编写符合标准软件开发实践的应用程序

Selenium Gird:分布式自动化工具,可以在多个测试环境中以并发的方式执行测试脚本,实现测试脚本,实现测试脚本的并发执行,缩短大量的测试脚本的执行时间

Maven项目构建

优点:

1.可以使用Maven来编译你的代码

2.项目打包也可以使用Maven来完成

3.maven可以实现项目模块化管理

4.maven可以在线管理依赖,项目依赖也很方便获取

5.maven提供了一些丰富的插件,方便项目持续集成

Maven安装和配置环境变量

1.官网下载:Maven – Download Apache Maven

2.配置环境变量

1.解压到本地文件夹

2.配置MAVEN_HOME环境变量,指向Maven文件夹

3.将Maven bin目录更新到PATH:%MAVEN_HOME%\bin

4.验证:mvn -version

5.修改setting.xml

1)指定本地仓库目录

<localRepository>D:\OtherTool\apache-maven-3.8.4\Maven_repository</localRepository>

2)配置镜像,指定下载jar包的地址

<mirrors>

<mirror>

<id>nexus-aliyun</id>

<name>Nexus aliyun</name>

<mirrorOf>central</mirrorOf>

<url>http://maven.aliyun.com/nexus/content/groups/public</url>

</mirror>

</mirrors>

3)Eclipse配置:

Window->Preference->Maven

修改Installations选项:点击添加指向本地maven根目录,点击Finish;勾选添加的本地Maven

4)修改User Settings选项

1.修改Global Setting指向本地maven 的setting.xml

2.修改User Settings指向用户自定义配置文件

6.Maven选项说明

1)Group Id 分组,一般填写组织机构,如com.lemon

2)Artifact Id—项目打包成jar包的id,或者jar包的名字

3)Version 版本

4)Packaging 打包方式

7.Maven项目结构

1)src/main/java—-一般是开发人员写代码的目录

2)src/main/resources—-开发人员放项目资源文件的目录

3)src/test/java—-放单元测试代码的目录

4)src/test/resources—-放测试资源文件的目录

5)maven Dependencies—通过maven拿下来的项目依赖包放目录

6)target—-存放构建后文件的目录

引入selenium框架

jar包配置搜索官方地址:http://mvnrepository.com/—-搜索selenium

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->

<dependency>

    <groupId>org.seleniumhq.selenium</groupId>

    <artifactId>selenium-java</artifactId>

    <version>3.141.59</version>

</dependency>

把上面的代码复制到maven项目的pom.xml下

可能会有错误,Eclipse可以参考:新系统中导入maven失败出错,Could not calculate build plan_sean-xiao的专栏-CSDN博客

IDEA可以参考:

<dependencies>

<dependency>   

<groupId>org.seleniumhq.selenium</groupId>  

 <artifactId>selenium-java</artifactId>        

<version>3.141.59</version>

</dependency>

</dependencies>

Chromer自动化环境配置问题参考:一文搞定web自动化环境常见问题 - 歪歪欧巴 - 博客园

idea创建Maven项目参考:IntelliJ IDEA 15 创建maven项目 - Tom1997 - 博客园

基本元素定位:

使用findElement(By.xpath)而不是driver.findElementByXPath(),是因为     driver.findElement(By.xpath())利于封装

1.id—-根据id来获取元素,id值一般是唯一的

2.name—-根据name来获取元素,可能会返回元素集合

3.tagname—-根据元素的标签名来获取元素,可能会返回元素集合

4.classname—根据元素的样机class值来获取元素,可能返回元素集合

5.linkText—-根据超链接的文本值来获取元素

6.partialLinkText—根据超链接的部分文本值来获取元素

//定位百度的搜索框元素,并且输入数据---ID定位---唯一

driver.findElement(By.id("kw")).sendKeys("柠檬班");

//定位百度的搜索框元素,并且输入数据---name定位---可能重复,可以ctrl+F先搜索查看

driver.findElement(By.name("wd")).sendKeys("腾讯视频");

//定位百度的搜索框元素,并且输入数据---tagName定位---找到多个元素--不推荐使用

 driver.findElement(By.tagName("input")).sendKeys("腾讯视频");

//定位百度的搜索框元素,并且输入数据---className定位

 driver.findElement(By.className("s_ipt")).sendKeys("腾讯视频");

//复合问题的解决方法---找其中一个的唯一值

// driver.findElement(By.className("bg s_btn")).click();  ---有问题

 driver.findElement(By.className("s_btn")).click(); ---正确

//定位"新闻"元素,并且点击---linkText定位

 driver.findElement(By.linkText("新闻")).click();

//定位"新闻"元素,并且点击---partailLinkText定位

driver.findElement(By.partialLinkText("共赴")).click();

//定位百度一下按钮,并点击----name定位

 driver.findElement(By.id("su")).click();

元素定位—-CSSSelector

1.根据TagName

By.cssSelector(”input”);

2.根据ID

By.cssSelector("input#id");

By.cssSelector("#id");

3.根据className(类名)

By.cssSelector(".className");

By.cssSelector("input.className");

4.css精确定位

根据元素属性,属性名==属性值,id,class等都可写出这种形式

By.cssSelector(”input[name=’XXX’]”)

5.多属性

By.cssSelector(”标签名[属性值1=’属性值‘][属性值2=’属性值‘]”);

// cssSelector元素定位

// (1)tagName定位---标签定位

driver.findElement(By.cssSelector("input"));

// (2)id定位

driver.findElement(By.cssSelector("#kw")).sendKeys("腾讯课堂");

// (3)className定位

 driver.findElement(By.cssSelector(".s_ipt")).sendKeys("腾讯课堂");

// (4)精确定位 根据元素属性,属性名==属性值,id,class等都可写出这种形式

driver.findElement(By.cssSelector("input[maxlength='255']")).sendKeys("腾讯课堂");

//多属性定位

driver.findElement(By.cssSelector("input[maxlength='255'][autocomplete='off']")).sendKeys("软件测试");

Xpath元素定位

一个描述页面位置信息的路径,相当于元素的坐标;Xpath基于xml文档树状结构,是xml路径语言,用来查询xml文档中的节点。

绝对定位:

从根目录开始找——/(根目录)

/html/body/div[2]/div/form/div[5]/button

缺点:一旦页面结构发送变化,该路径也随之失效,必须重新写

相对路径:只要不是/开始的,就是相对路径

//*[@name=’phone’]

路径解释:

1)//匹配指定节点,不考虑它们的位置(/则表示绝对路径,从根下开始)

2)*通配符,匹配任意节点

3)@选取属性

4)[]属性判断条件表达式

相对定位优点:

灵活,方便,耦合性低

元素操作API

1)click():触发当前元素的点击事件

2)clear():清空内容

3)sendkeys:往文本框一类元素中写入元素

4)getTagName():获取元素的标签名

5)getAttribue():根据属性名获取元素属性值

6)getText():获取当前元素的文本值

7)isDisplayed():查看元素是否显示

sendKeys 发送    

driver.findElement(By.id("kw")).sendKeys("12345");      

//等待3秒//       

Thread.sleep(3000);     

//clear:清除内容       

driver.findElement(By.id("kw")).clear();       

WebElement webElement1 = driver.findElement(By.id("kw"));       

// 4)getTagName():获取元素的标签名       

System.out.println("得到元素的标签名"+webElement1.getTagName());      

 //5)getAttribue():根据属性名获取元素属性值       

System.out.println("得到元素的maxlength属性"+webElement1.getAttribute("maxlength"));       

WebElement webElement2 = driver.findElement(By.xpath("//a[text()='hao123']"));       

// 6)getText():获取当前元素的文本值      

 System.out.println("webElement2的文本值"+webElement2.getText());       

// 7)isDisplayed():查看元素是否显示       

System.out.println("元素的是否显示"+webElement2.isDisplayed());

WebDriver相关API

1)get(String url):访问指定url页面

2)getCurrentUrl():获取当前页面的url地址

3)getTitle:获取当前页面的标题

4)getPageSource():获取当前页面源代码

5)quit():关闭驱动对象以及所有相关的窗口

6)close():关闭当前窗口

7)getWindowHandle():返回当前页面句柄

8)getWindowHandles():返回所有由驱动对象打开页面所有的句柄,页面不同,句柄不一样

9)manage():此方法可以获取Options—-浏览器菜单操作对象  ,driver.manage().window()

//1)get(String url):访问指定url页面      

//2)getCurrentUrl():获取当前页面的url地址       

System.out.println("当前的url为"+driver.getCurrentUrl());      

//3)getTitle:获取当前页面的标题        

System.out.println("获取当前页面的标题"+driver.getTitle());    

//4)getPageSource():获取当前页面源代码       

System.out.println("获取当前页面源代码"+driver.getPageSource());     

//5)quit():关闭驱动对象以及所有相关的窗口       

driver.quit();

navigate对象:

//获取navigate对象

Navigation navigation = driver.navigate();

//访问京东

navigation.to("https://www.jd.com");

//刷新网页

navigation.refresh();

//回退

navigation.back();

//前进

navigation.forward();

三大等待

1)硬性等待

Thread.sheep();

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class ElementWait {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //访问百度
        driver.get("https://baidu.com");
        //findElement查找一个元素对象并返回元素对象
        driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
        driver.findElement(By.id("su")).click();
        Thread.sleep(3000);
        driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();

    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();


    }
}

2)显示等待

1)用来等待某个条件发送后在继承执行后续代码(如找到元素、元素可点击、元素已显示等)

2)设置方法:

WebDriverWait wait = new WebDriverWait(driver,timeout);//driver:浏览器驱动;timeout:最长超时时间,默认以秒为单位

WebElement element = wait.until(expectCondition);

方法

等待条件

visibilityOfElementLocated(By locator)

页面元素在页面存在并且可见

elememtToBeClickable(By locator)

页面元素是否在页面上可用和可被点击

elementToBeSelected(WebElement element)

页面元素处于被选中状态

TextToBePresentlnElement(By locator)

在页面元素中是否包含特定的文本

presenceOfElementLocated(By locator)

页面元素在页面中存在

import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.concurrent.TimeUnit;

public class ElementWait3 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();

        //访问百度
        driver.get("https://baidu.com");
        //findElement查找一个元素对象并返回元素对象
        driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
        driver.findElement(By.id("su")).click();
        //显示等待
        WebDriverWait wait = new WebDriverWait(driver,5);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[text()=' —专业在线学习平台']")));

        driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

3)隐形等待

a.设置的超时时间范围内不断查找元素,直到找到元素或者超时

b.  driver.manage.timeouts().implicityWait(long time,TimeUnit unit);

优点:相对灵活

缺点:设置是针对全局的,在WebDriver实例整个生命周期有效,但并不是所有的元素都需要等待

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.concurrent.TimeUnit;

public class ElementWait2 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();

        //在driver实例化完成之后设置隐式等待,设置超时的时间为5S
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        //访问百度
        driver.get("https://baidu.com");
        //findElement查找一个元素对象并返回元素对象
        driver.findElement(By.id("kw")).sendKeys("腾讯课堂");
        driver.findElement(By.id("su")).click();
        driver.findElement(By.xpath("//a[text()=' —专业在线学习平台']")).click();

    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作

特殊元素定位与操作---模态框

Modle Dialogue Box,又叫做模拟对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应,如单击[确定]和[取消]按钮等将该对话框关闭

1)alert

2)confirm

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SpecialElementLocate {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //comfirm弹框处理
    //访问本地的HTML文件
         driver.get("E:\\test\\HTML\\Untitled-3.html");
         driver.findElement(By.id("abn")).click();
         Thread.sleep(3000);
         //找到对应的comfirm框
        Alert alert = driver.switchTo().alert();
        alert.accept();
      //  alert.dismiss();
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作---iframe切换

四种方式切换

1)driver.switchTo().frame(index);

2)driver.switchTo().frame(id);

3)driver.switchTo().frame(name);

4)driver.switchTo().frame(WebElement);

切换之后,回到默认内容页面(否则会找不到元素)

driver.switchTo().defaultContent();

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

public class SpecialElementLocate2 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //iframe
        driver.get("E:\\test\\HTML\\Untitled-3.html");
        //在默认的页面去找输入框输入数据
        driver.findElement(By.id("aa")).sendKeys("111");
        Thread.sleep(3000);
        //进入第一个内嵌页面中定位元素,输入数据
        driver.switchTo().frame("bframe");
        driver.findElement(By.id("bb")).sendKeys("2222");
        Thread.sleep(3000);
        //进入第二个内嵌页面中定位元素,输入数据
        driver.switchTo().frame("cframe");
        driver.findElement(By.id("cc")).sendKeys("3333");
        Thread.sleep(3000);
        //返回默认的内容页面
        driver.switchTo().defaultContent().sendKeys("回到默认页面");

    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作---window

当你要操作另一个窗口页面的元素时,一定要注意先切换窗口

切换方式:传入要操作窗口的name或者句柄handle

driver.switchTo().window(name Or handle);

如何获取到窗口的句柄:

1)driver.getWindowHandle();//获取当前操作窗口的句柄

2)driver.getWindowHandles();//获取测试时打开的所有窗口句柄

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class SpecialElementLocate23 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //window处理
        driver.get("E:\\test\\HTML\\Untitled-3.html");
        driver.findElement(By.id("aa")).sendKeys("这是第一个窗口");
        System.out.println("跳转后的窗口句柄"+driver.getWindowHandle());
        Thread.sleep(2000);
        //切换到B窗口
        driver.findElement(By.id("bb")).click();
        //虽然页面已经到了B窗口,但是句柄还是在A窗口,所有还是在A窗口上操作
        Thread.sleep(2000);
        System.out.println("跳转后的窗口句柄"+driver.getWindowHandle());
        //句柄的切换
        //进入b的窗口之后,获取到所有窗口的句柄
        Set<String> handles = driver.getWindowHandles();
        //对窗口进行遍历
        for (String handle : handles){
            //切换句柄
            driver.switchTo().window(handle);
            //如何知道就是处于B窗口了呢
            if (driver.getTitle().equals("b.html")){
                //若标题是符合就跳出循环
                break;
            }
        }
        driver.findElement(By.id("bb")).sendKeys("这是第二个窗口");
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作---select下拉框

如果页面元素是一个下拉框,我们可以将此web元素封装为select对象

Select select = new Select(WebElement element);

Select对象常用API

1)select.getOptions();//获取所有的选项

2)select.selectByIndex(index); //根据索引选中对应的元素

3)select.selectByValue(value);//选择指定value值对应的选项

4)select.selectByVisible(text);//选中文本值对应的选项

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;


import java.util.Set;

public class SpecialElementLocate4 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //select下拉框处理
        driver.get("https://www.baidu.com");
        Thread.sleep(3000);
       // driver.findElement(By.xpath("//div[@id='ul']/a[text()='设置']")).click();
        driver.findElement(By.xpath("//*[@id=\"s-usersetting-top\"]")).click();
        driver.findElement(By.xpath("//a[text()='高级搜索']")).click();
        Thread.sleep(3000);


        //定位下拉框 ----这是之前的设置
        WebElement webElement = driver.findElement(By.name("gpc"));
        //把 webElement封装成select对象
        Select select = new Select(webElement);
        //select下拉框索引值从0开始
        select.selectByIndex(1);
        Thread.sleep(2000);
        select.selectByVisibleText("最近一月");


        //这是2022.1月百度的下拉框设置
         //定位下拉框--先定位到下拉的箭头后等待几秒
        driver.findElement(By.xpath("//*[@id=\"adv-setting-gpc\"]/div/div[1]/i[1]")).click();
        Thread.sleep(3000);
        driver.findElement(By.xpath("//*[@id=\"adv-setting-gpc\"]/div/div[2]/div[2]/p[4]")).click();
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作---时间日期控件

分两种情况:

1)控件没有限制手动输入,则直接调用sendKeys方法写入时间数据

2)控件有限制输入,则可以执行一段js来改变元素的value属性值

JavascriptExecutor jsexecutor = (JavascriptExecutor) driver;

jsexecutor.executeScript("...");

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.chrome.ChromeDriver;

public class SpecialElementLocate5 {

    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //时间日期控件(1)
    //    driver.get("https://www.fliggy.com/?ttid=seo.000000574&seoType=origin");
        //sendKeys直接输入
     //   driver.findElement(By.xpath("//*[@id=\"J_FlightForm\"]/fieldset/div[3]/div/div/input")).sendKeys("2020");
      
      
        //时间日期控件(2)
        driver.get("https://www.12306.cn/index/");
        //先清除input内原有的数据,再输入新的数据
        driver.findElement(By.xpath("//*[@id=\"train_date\"]")).clear();
        Thread.sleep(3000);
        driver.findElement(By.xpath("//*[@id=\"train_date\"]")).sendKeys("2022");

       // 时间日期控件(3)
        //限制输入的时间日期控件
        driver.get("https://www.12306.cn/index/");
        JavascriptExecutor jsexecutor = (JavascriptExecutor) driver;
        jsexecutor.executeScript("document.getElementById(\"train_data\").removeAttribute(\"readonly\")");
        Thread.sleep(2000);
        driver.findElement(By.id("train_data")).clear();
        Thread.sleep(2000);
        driver.findElement(By.id("train_data")).sendKeys("2020-01-01");
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }
}

特殊元素定位与操作---鼠标操作

由于一些元素不适合直接点击或者进行某些操作时,可以使用Selenium的Actions类来模拟鼠标键盘操作,通过Actions对象可以发起鼠标左键,右键,移动鼠标等操作,最后使用perform方法执行操作

actions.clickAndHold(onElement).moveToElement(toElement).relrese().build().perform();
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

public class SpecialElementLocate6 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //鼠标操作
        driver.get("http://www.treejs.cn/v3/demo/cn/exedit/drag.html");
        WebElement sourceElement = driver.findElement(By.id("treeDemo_2_span"));
        WebElement targetElement = driver.findElement(By.id("treeDemo_3_span"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(sourceElement).moveToElement(targetElement).release().build().perform();
    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }

}

特殊元素定位与操作---文件操作

分为两种情况

1)类似下面,使用sendKeys写入文件的路径

<input type=”file” id=”du” value=”选择文件”>

2)如果文件上传不是input元素,而是使用的第三方的控件,并且不是input元素,那么这种情况就很棘手了,必须使用第三方的工具,比如autoit等来完成。

import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;

public class SpecialElementLocate7 {
    private static ChromeDriver driver;

    public static void main(String[] args) throws InterruptedException {
        openChrome();
        //文件上传
        driver.get("E:\\test\\HTML\\Untitled-1.html");
        //选择文件
        driver.findElement(By.xpath("//input[@value='选择文件']")).sendKeys("D:\\1.png");
        Thread.sleep(3000);
        //点击上传按钮
        driver.findElement(By.xpath("//input[@value='上传']")).click();

    }

    public static void openChrome() {
        System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
        //打开浏览器
        driver = new ChromeDriver();
    }

}

特殊元素定位与操作---验证码

1)去除验证码

2)自动识别

3)万能验证码(推荐)--参考CSDNicon-default.png?t=M0H8https://mp.csdn.net/mp_blog/creation/editor/122598469

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值