• java+selenium——详解介绍Selenium常用API的使用Java语言(完整版)


    官方API文档:https://selenium.dev/selenium/docs/api/java/index.html

    参考:https://blog.csdn.net/qq_22003641/article/details/79137327?utm_source=distribute.pc_relevant.none-task

    参考:https://blog.csdn.net/woiangaoiowe/article/details/99285868

    参考:https://blog.csdn.net/woiangaoiowe

    参考:https://blog.csdn.net/df0128/category_3060581.html

    =================================================================================================================================================

    driver.findElementById("kw")

    ……


    引入包:import org.openqa.selenium.By;


    driver.findElement(By.id())

    driver.findElement(By.name())

    driver.findElement(By.className())

    driver.findElement(By.tagName())

    driver.findElement(By.linkText())

    driver.findElement(By.partialLinkText())

    driver.findElement(By.xpath())

    driver.findElement(By.cssSelector())


    定位一组元素:


    driver.findElements(By.id())

    driver.findElements(By.name())

    driver.findElements(By.className())

    driver.findElements(By.tagName())

    driver.findElements(By.linkText())

    driver.findElements(By.partialLinkText())

    driver.findElements(By.xpath())

    driver.findElements(By.cssSelector())

    ==========================================================================================================================================

    Eclipse中通过对象名.方法名即可调出所有Web Element的方法:参考网址:https://blog.csdn.net/woiangaoiowe/article/details/99285868


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

    clear():void——如果元素是一个文本类型的元素,则我们可以通过该方法来清空文本内容。语法:element.clrea();


    sendkeys():void——向元素中填入值


    click():void——这个方法模拟用户在UI页面上点击元素的动作


    isDisplayed():Boolean——该方法用来判断页面上该元素当前是否显示


    isEnabled():boolean——用来判断界面元素是否是可用的,返回值为boolean值。返回boolean值,则可以考虑结合判断语句一起使用


    isSelected():boolean——通过该方法来判断界面上的某个元素是否是选中状态


    submit():boolean——通过该方法用来提交form表单。html中我们学习到form表单是通过submit方法来提交的,所以针对form元素,selenium也同样提供了我们submit这种提交数据的方法。


    gettext():String——获取元素的文本内容。什么是文本内容?就是html尖括号对中间所写的文字


    getTagName():String——tagname即html标签的标签类型,比如a、input、table等。


    getCssValue():String——获取元素的css样式的值,入参string类型为元素内某个样式名称,比如背景色、长、宽等


    getAttribute():String——获取元素内属性的值,入参内容为元素的某个属性名称


    getLocation():Point——获取元素在页面上的坐标位置


    ==============================================================================================================================


    键盘按键操作:

    引入包:import org.openqa.selenium.Keys;

    driver.findElement(By.id("ks")).sendKeys(Keys.CONTROL,"a"); ctrl +A 全选

    driver.findElement(By.id("ks")).sendKeys(Keys.CONTROL,"X"); ctrl +X 剪切

    driver.findElement(By.id("ks")).sendKeys(Keys.CONTROL,"C"); ctrl +C 复制

    driver.findElement(By.id("ks")).sendKeys(Keys.CONTROL,"V"); ctrl +V 粘贴

    driver.findElement(By.id("ks")).sendKeys(Keys.ENTER);  回车

    driver.findElement(By.id("ks")).sendKeys(Keys.BACK_SPACE);  删除

    driver.findElement(By.id("ks")).sendKeys(Keys.SPACE);  空格

    ================================================================================================================================================
    ================================================================================================================================================
    ================================================================================================================================================
    ================================================================================================================================================
    ================================================================================================================================================
    ================================================================================================================================================


    import org.openqa.selenium.Dimension;
    import org.openqa.selenium.Point;
    import org.openqa.selenium.firefox.FirefoxDriver;

    public class xinkaishi
    {


    public static void main(String[] args)

    {
    System.setProperty("webdriver.firefox.bin","C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //设置火狐的安装路径,防止系统找不到

    FirefoxDriver driver = new FirefoxDriver(); //初始化FireFox浏览器实例,并打开浏览器

    try
    {
    driver.manage().window().maximize(); //最大化窗口
    Thread.sleep(5000);

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    设置浏览器在屏幕的位置:

    引入包:import org.openqa.selenium.Point;

    Point point = new Point(150,150); //声明一个Point对象,两个150表示浏览器左上角的位置与屏幕左上角(0,0)的横坐标距离和纵坐标距离。
    driver.manage().window().setPosition(point); //设置浏览器在屏幕的位置
    System.out.println(driver.manage().window().getPosition()); //获取浏览器在屏幕的位置

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    设置浏览器的长度和宽度:


    引入包:import org.openqa.selenium.Dimension;


    Dimension dimension = new Dimension(500,500); //声明一个Dimension,表示浏览器的长度和宽度
    driver.manage().window().setSize(dimension); //设置浏览器的长度和宽度,长度为x方向,宽度为y方向
    System.out.println(driver.manage().window().getSize()); //获取浏览器窗口的大小


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    driver.get("http://www.baidu.com"); //访问一个网页方法一

    driver.navigate().to("http://www.hao123.com"); //访问一个网页方法二

    driver.navigate().back(); //返回第一次访问的网页,即后退功能

    driver.navigate().forward(); //前进功能

    driver.navigate().refresh(); //刷新当前页面


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    driver.getTitle() //打印当前打开网页的标题

    driver.getCurrentUrl() //打印当前打开网页的网址

    driver.getPageSource() //打印当前页面源代码


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    文本框清空和输入、以及单击按钮操作:

    driver.findElementById("kw").clear(); //文本框里清空

    driver.findElementById("kw").sendKeys("china"); //文本框里输入

    driver.findElementById("su").click(); //点击确定(搜索)按钮


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    杀掉一个浏览器进程:

    引入包:import org.openqa.selenium.os.WindowsUtils;


    WindowsUtils.killByName("firefox.exe"); //引入包import org.openqa.selenium.os.WindowsUtils;

    WindowsUtils.killByName("iexplore.exe"); //引入包import org.openqa.selenium.os.WindowsUtils;

    WindowsUtils.killByName("chrome.exe"); //引入包import org.openqa.selenium.os.WindowsUtils;

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    driver.getWindowHandle(); //先将当前浏览器窗口句柄存储到变量中


    driver.getWindowHandles(); //获取浏览器窗口的所有句柄


    driver.switchTo().window(windowHandle) //切换浏览器窗口


    Set<String> allWindowsHandles = driver.getWindowHandles(); //把打开的所有浏览器句柄,存放到一个set容器中


    if ( !allWindowsHandles.isEmpty() )
    {
    for ( String windowHandle : allWindowsHandles )
    {
    System.out.println(driver.switchTo().window(windowHandle).getTitle());

    Thread.sleep(10000);
    }
    }

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作JavaScript的3个弹框对比总结:

    引入包:import org.openqa.selenium.Alert;

    js的alert弹框:


    Alert alert = driver.switchTo().alert(); //获取并创建alert对象

    alert.getText(); //获取弹出框中的文字

    alert.accept(); //点击弹出框上面的确定按钮

    --------------------------------------------------------------------------------


    js的confirm弹框:

    Alert alert = driver.switchTo().alert(); //获取并创建alert对象

    alert.getText(); //获取弹出框中的文字

    alert.accept(); //点击弹出框上面的确定按钮

    alert.dismiss(); //点击弹出框上面的取消按钮


    --------------------------------------------------------------------------------


    js的prompt弹框:


    Alert alert = driver.switchTo().alert(); //获取并创建alert对象

    alert.getText(); //获取弹出框中的文字

    alert.sendKeys("…………"); //输入内容

    alert.accept(); //点击弹出框上面的确定按钮

    alert.dismiss(); //点击弹出框上面的取消按钮


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    frame切换:

    driver.switchTo().frame(""); //也可以通过索引来切换比如:driver.switchTo().frame(1);

    driver.switchTo().defaultContent(); //返回主页面


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    执行js脚本:


    引入包:import org.openqa.selenium.JavascriptExecutor;


    JavascriptExecutor js = ( JavascriptExecutor ) driver; //声明一个js执行器

    String title = (String) js.executeScript("return document.title"); //调用执行器的executeScript方法执行js脚本

    System.out.println(title); //打印的是当前浏览器的title值


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    操作浏览器的cookie:

    driver.manage().getCookies(); //获取当前页面下所有cookies

    driver.manage().deleteAllCookies(); //删除所有cookies

    driver.manage().deleteCookieNamed("cookie的某个key值"); //删除某个指定的cookie

    driver.manage().getCookieNamed("username").getValue(); // 以name获取cookie

    driver.manage().getCookies().size(); // 获取所有cookie个数

    // 增加cookie
    Cookie cookie = new Cookie("username", "name", "/", null);
    driver.manage().addCookie(cookie);
    driver.manage().addCookie(new Cookie("password", "ppppwwww", "/", null));


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    格式化时间:


    引入包:import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;

    DateFormat dateformat1= new SimpleDateFormat("yyyy-MM-dd"); //创建一个data format对象
    Date date1 = new Date(); //利用Date()获取当前时间
    String datex = dateformat1.format(date1); //格式化时间,并用String对象存储
    System.out.println(datex); //打印格式化时间到控制台:2020-02-11

    DateFormat dateformat2= new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); //创建一个data format对象
    Date date2 = new Date(); //利用Date()获取当前时间
    String datey = dateformat2.format(date2); //格式化时间,并用String对象存储
    System.out.println(datey); //打印格式化时间到控制台:2020-02-11-16-35-11



    DateFormat dateformat3= new SimpleDateFormat("HH-mm-ss"); //创建一个data format对象
    Date date3 = new Date(); //利用Date()获取当前时间
    String dateu = dateformat3.format(date3); //格式化时间,并用String对象存储
    System.out.println(dateu); //打印格式化时间到控制台:16-35-11


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    截图保存到指定文件夹:


    引入包:import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;

    import java.io.File;
    import org.apache.commons.io.FileUtils;


    DateFormat dateformat1= new SimpleDateFormat("yyyy-MM-dd"); //创建一个data format对象
    Date date1 = new Date(); //利用Date()获取当前时间
    String datex = dateformat1.format(date1); //格式化时间,并用String对象存储
    System.out.println(datex); //打印格式化时间到控制台:2020-02-11

    DateFormat dateformat2= new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); //创建一个data format对象
    Date date2 = new Date(); //利用Date()获取当前时间
    String datey = dateformat2.format(date2); //格式化时间,并用String对象存储
    System.out.println(datey); //打印格式化时间到控制台:2020-02-11-20-44-54



    DateFormat dateformat3= new SimpleDateFormat("HH-mm-ss"); //创建一个data format对象
    Date date3 = new Date(); //利用Date()获取当前时间
    String dateu = dateformat3.format(date3); //格式化时间,并用String对象存储
    System.out.println(dateu); //打印格式化时间到控制台:20-44-54


    File src02= ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); // 调用截图方法
    FileUtils.copyFile(src02, new File("C:\\Users\\del\\Desktop\\"+datex, dateu + ".png"));


    //新建的文件夹名:2020-02-11 文件名称:20-44-54.png


    File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

    FileUtils.copyFile(scrFile, new File("C:\\Users\\del\\Desktop\\新建文件夹 (2)\\xxx.png"));

    //保存到已经存在文件夹下面,并且取个名字

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    模拟键盘操作:


    引入包:import org.openqa.selenium.interactions.Actions;
    import org.openqa.selenium.Keys;


    driver.findElementById("kw").sendKeys("seleniumm");

    Actions action = new Actions(driver);

    action.sendKeys(driver.findElementById("kw"),Keys.BACK_SPACE).perform(); //删除多于的l字母

    action.keyDown(Keys.CONTROL).sendKeys("a").keyUp(Keys.CONTROL).perform(); //ctrl+a

    action.keyDown(Keys.CONTROL).sendKeys("c").keyUp(Keys.CONTROL).perform(); //ctrl+c

    action.keyDown(Keys.CONTROL).sendKeys("v").keyUp(Keys.CONTROL).perform(); //ctrl+v


    -------------------------------------------------------------------------------------------------------------------


    driver.findElementById("kw").sendKeys(Keys.chord(Keys.CONTROL, "a")); //ctrl+a

    driver.findElementById("kw").sendKeys(Keys.chord(Keys.CONTROL, "c")); //ctrl+c

    driver.findElementById("kw").sendKeys(Keys.chord(Keys.CONTROL, "v")); //ctrl+v

    driver.findElementById("su").sendKeys(Keys.ENTER);


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    模拟键盘操作:


    引入包;import java.awt.datatransfer.StringSelection;
    import java.awt.event.KeyEvent;
    import java.awt.Robot;
    import java.awt.Toolkit;


    String a = "中国"; //将a这个字符串放入到剪切板中

    StringSelection stringSelection = new StringSelection(a);

    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection,null);


    driver.findElementById("kw").sendKeys("中国");

    Robot robot = new Robot();

    robot.keyPress(KeyEvent.VK_CONTROL); //按下ctrl键

    robot.keyPress(KeyEvent.VK_V); //按下V键

    robot.keyRelease(KeyEvent.VK_V); //释放v键

    robot.keyRelease(KeyEvent.VK_CONTROL); //释放ctrl键

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    模拟鼠标右击:


    引入包:import org.openqa.selenium.interactions.Actions;


    Actions action = new Actions(driver);

    action.contextClick(driver.findElementByLinkText("地图")).perform(); //鼠标在某个元素上右击

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    模拟鼠标悬浮:


    引入包:import org.openqa.selenium.interactions.Actions;


    ctions action = new Actions(driver);

    action.moveToElement(driver.findElementByLinkText("设置")).perform(); //鼠标悬浮在 设置 元素上面

    driver.findElementByClassName("setpref").click(); // 打开搜索设置


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作单选按钮:


    引入包:import org.openqa.selenium.WebElement;
    import java.util.List;


    WebElement radioOption = driver.findElement(By.xpath("//input[@value='berry']")); //查找某个指定的按钮

    if ( radioOption.isSelected() ==false )

    radioOption.click();

    List<WebElement> dx = driver.findElements(By.name("SL")); //将name属性为SL的所有单选按钮对象,存储到一个list容器中

    for ( WebElement d : dx ) //使用for循环遍历list容器中的每一个单选按钮,查找value=2的单选按钮
    { //如果查询到此按钮没有被选中,则单击选择
    if ( d.getAttribute("value").equals("2"))
    {
    if ( !d.isSelected())
    d.click();
    }
    }

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作复选框:


    引入包:import org.openqa.selenium.WebElement;
    import java.util.List;


    WebElement orangeCheckbox = driver.findElement(By.xpath("//input[@value='orange']")); //查找value属性为orange的复选框元素

    if ( orangeCheckbox.isSelected() == false ) //如果未被选择,则选中

    orangeCheckbox.click();


    if ( orangeCheckbox.isSelected() == true ) //如果选中了,则取消选中

    orangeCheckbox.click();


    List<WebElement> checkboxs = driver.findElements(By.name("fruit")); //把所有的复选框放进list容器中,进行遍历,全部处于选中状态

    for( webElement checkbox : checkboxs )

    checkbox.click();


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作单选下拉框:

    引入包:import org.openqa.selenium.support.ui.Select;


    Select dropList = new Select(driver.findElement(By.Name("NR")));

    System.out.println(dropList.getFirstSelectedOption().getText()); //查看刚开始默认选择的选项

    Boolean a = dropList.isMultiple(); //是否允许多选,允许多选返回true,否则 不允许返回false

    System.out.println(a); // 此处不允许多选,返回false


    //selectByIndex()方法,通过索引进行选中,3个选项,索引从0开始,即 0,1,2

    dropList.selectByIndex(1); //3个选项,索引从0开始,即 0,1,2

    System.out.println(dropList.getFirstSelectedOption().getText());


    //selectByVisibleText()方法,通过选项的文字进行选中

    dropList.selectByVisibleText("每页显示20条");

    System.out.println(dropList.getFirstSelectedOption().getText());


    //selectByValue()方法,使用下来列表的属性的value属性值进行选中操作

    dropList.selectByValue("20");

    System.out.println(dropList.getFirstSelectedOption().getText());


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作单选下拉框,检查单选列表的选项文字知否符合期望:

    引入包:import org.openqa.selenium.support.ui.Select;
    import java.util.List;


    Select dropList = new Select(driver.findElement(By.Name("fruit")));


    List<String> expect_options = Arrays.asList((new String[]{"桃子","西瓜","香蕉"}));

    List<String> actual_option = new ArrayList<String>();

    for ( WebElement option : dropList.getOptions() ) //dropList.getOptions()用于获取页面上下拉列表中的所有选项对象

    actual_option.add( option.getText());

    Assert.assertEquals( expect_options.toArray(),actual_option.toArray()); //断言两个数组对象是否完全一致

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    操作多选下拉框:

    引入包:import java.util.List;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.interactions.Actions;
    import org.openqa.selenium.support.ui.Select;


    Select dropList = new Select(driver.findElementByName("NR"));



    System.out.println(dropList.getFirstSelectedOption().getText()); //查看刚开始默认选择的选项

    Boolean a = dropList.isMultiple(); //是否允许多选,允许多选返回true,否则 不允许返回false

    System.out.println(a); // 此处允许多选,返回true

    List<WebElement> options = dropList.getOptions();

    for (WebElement option : options )
    {
    System.out.println(option.getText()); //打印出所有选项
    }


    //通过3种不同方法,选择3个状态

    dropList.selectByIndex(0); //selectByIndex()方法,通过索引进行选中,3个选项,索引从0开始,即 0,1,2
    dropList.selectByVisibleText("每页显示50条"); //selectByVisibleText()方法,通过选项的文字进行选中
    dropList.selectByValue("20"); //selectByValue()方法,使用下来列表的属性的value属性值进行选中操作

    dropList.deselectAll(); //取消所有选项的选中状态




    //再次通过3种不同方法,选择3个状态

    dropList.selectByIndex(0); //selectByIndex()方法,通过索引进行选中,3个选项,索引从0开始,即 0,1,2
    dropList.selectByVisibleText("每页显示50条"); //selectByVisibleText()方法,通过选项的文字进行选中
    dropList.selectByValue("20"); //selectByValue()方法,使用下来列表的属性的value属性值进行选中操作



    dropList.deselectByIndex(0); //通过索引取消选中状态
    dropList.deselectByVisibleText("每页显示50条"); //通过选项文字取消选中状态
    dropList.deselectByValue("20"); //通过value值取消选中状态

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    }catch (Exception e)
    {
    e.printStackTrace();
    }finally
    {
    driver.quit(); //完全退出浏览器

    //driver.close(); //相当于关闭当前tab窗口

    }
    }



    }

  • 相关阅读:
    Angular 从入坑到挖坑
    如何获取 C# 类中发生数据变化的属性信息
    我的领域驱动设计运用实例
    Newbe.Claptrap
    体验 QQ机器人C# SDK 1.X 特性总结
    Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?
    轻松应对并发问题 Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车
    谈反应式编程在服务端中的应用,数据库操作优化,提速 Upsert
    十万同时在线用户,需要多少内存?——Newbe.Claptrap 框架水平扩展实验
    docker-mcr 助您全速下载 dotnet 镜像
  • 原文地址:https://www.cnblogs.com/xiaobaibailongma/p/12329246.html
Copyright © 2020-2023  润新知