IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> APP自动化-显示等待/强制等待/命令等待 -> 正文阅读

[开发测试]APP自动化-显示等待/强制等待/命令等待

作者:token triple-quoted-string string

Selenium显性等待

# 导入库 
from selenium import webdriver 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as ECS 
from selenium.webdriver.common.by import By 
import time 
 
# executable_path 用于指定driver存放路径 
browser = webdriver.Chrome(executable_path='/Users/xx/python/chromedriver') 
 
# 打开京东官网 
browser.get('https://www.baidu.com/') 
 
# 定位要查找的元素 
loc = (By.LINK_TEXT, "关于百度") 
 
try: 
  # 等待5秒,直到发现元素 
    WebDriverWait(driver, 5).until(ECS.presence_of_element_located(loc)) 
except: 
  # 没有发现元素则会打印提示 
    print("没有找到对应元素!") 
finally: 
  # 发现元素则执行下面的方法 
    driver.find_element_by_link_text('关于百度').click() 
 
#退出浏览器 
browser.quit(

知道显性等待怎么用了,接下来我们来看下,还有哪些其他常见的使用方式:

先来个简单的,这里通过页面标题来判断

#元素等待直到能定位到元素,这里是定位到搜索输入框 
#这里定位时不关心元素是否可见,只要是加载到DOM中能定位到即可 
WebDriverWait(driver,3).until(ECS.presence_of_element_located((By.ID,'kw'))) 
 
#元素等待直到能定位到可见的元素,比如这里定位到搜索按钮 
#和上面不同,这里等待的元素除加载DOM中,也必须可见 
WebDriverWait(driver,3).until(ECS.visibility_of_element_located((By.ID,'su'))) 
 
#元素等待直到能定位到可见的元素,比如这里定位到搜索框 
#这个方法和上面 `visibility_of_element_located` 使用类似 
WebDriverWait(driver,3).until(ECS.visibility_of((By.ID,value='su'))) 
 
#元素等待直到通过 `CSS` 定位到至少有一个元素存在,则结束等待 
WebDriverWait(driver,3).until(ECS.presence_of_all_elements_located((By.CSS_SELECTOR,'.uinv'))) 
 
#这和上一个等待方法类似,主要就是需要元素可见才会结束等待 
WebDriverWait(driver,3).until(ECS.visibility_of_any_elements_located((By.CSS_SELECTOR,'.uinv'))) 
 
#元素等待直到元素被加载,可以定位到并且元素必须为不可见状态,才会结束等待 
WebDriverWait(driver,3).until(ECS.invisibility_of_element_located((By.CSS_SELECTOR,'#nwWrap')))```
在平时使用中,也经常会用到等待的元素包含某些内容来判断,而且这种方式能适用很多场景

在平时使用中,也经常会用到等待的元素包含某些内容来判断,而且这种方式能适用很多场景

#元素等待直到定位到指定的元素,并且元素的属性值中包含指定的字符串 
WebDriverWait(driver,3).until(ECS.text_to_be_present_in_element((By.XPATH,"//*[@id='bottom_layer']/div/p[1]/a"),'关于百度')) 
 
#这种实现跟上面效果差不多 
WebDriverWait(driver,3).until(ECS.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),'百度一下')) 

下面几种方式主要是针对下拉框类型的等待,还有可点击的组件,如超链接

#元素等待直到元素被加载,为可见状态,并且是可点击的状态,才会结束等待 
WebDriverWait(driver,3).until(ECS.element_to_be_clickable((By.XPATH,"//*[@id='bottom_layer']/div/p[1]/a"))).click() 
 
#元素等待直到元素被加载,可见状态并且这个元素是被选中的状态 
#这种方式我运用于下拉选择框 
WebDriverWait(driver,3).until(ECS.element_to_be_selected((By.XPATH,"//*[@id='sel']/option[2]"))) 
 
#元素等待直到元素被加载后,并且元素选中状态为预期的状态,才会结束等待 
WebDriverWait(driver,3).until(ECS.element_selection_state_to_be((By.XPATH,"//*[@id='sel']/option[1]"),False)) 

以下是比较特殊的几种方式,在某些情况下用处很大

# 元素等待直到页面加载出现 `alert`,出现自己切换过去并将提示内容返回 
WebDriverWait(driver,3).until(ECS.alert_is_present()) 
 
# 其他都是等待加载元素并操作,这种是等待元素被从Dom中移除时,才会触发结束等待 
WebDriverWait(driver,3).until(ECS.staleness_of(driver.find_element(By.ID,'su'))) 
 
# 这种是页面有多个Frame时,等待页面加载直到 `frame1` 可以切换进去,这时就会自动切换到 `frame1` ,然后结束等待 
WebDriverWait(driver,3).until(ECS.frame_to_be_available_and_switch_to_it(frame1)) 

实例

import random
from appium import webdriver
'''
导入显性等待模块
'''
from selenium.webdriver.support.wait import  WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy

'''
#页面渲染,显性等待WebDriverWait(driver,超时的时间)。until:等待它达成某一个事件
WebDriverWait(driver,10).until(EC.presence_of_element_located()) #等待一个元素存在于界面代码中,资源加载好了,还没渲染的情况下
WebDriverWait(driver,10).until(EC.visibility_of_element_located()) #等待一个元素显示于界面中,资源加载好了,也渲染出了它的样子(displayed=ture),对其他属性不一定渲染出来了
WebDriverWait(driver,10).until(EC.invisibility_of_element_located()) ##等待一个元素显示于界面中,资源加载好了,没有渲染出了它的样子(displayed=flase),对其他属性不一定渲染出来了
WebDriverWait(driver,10).until(EC.element_to_be_clickable()) # #等待一个元素显示于界面中,资源加载好了,也渲染出了它的样子(displayed=ture),对其他属性(clickable==true)一定渲染出来了,一定可以被点击的元素
WebDriverWait(driver,10).until(EC.element_to_be_selected())#等待一个元素显示于界面中,资源加载好了,也渲染出了它的样子(displayed=ture),对其他属性(selected=ture)一定渲染出来了,一定可以被选择的元素
'''
"""
脚本目的:
验证通过搜索功能的书籍,与从书城中获取的书籍一致

"""


'''
步骤:
a、打开读书屋,进入书城(需要构建一个会话)
'''
#启动方法一 需要包名和活动名
# desired_caps={
#     "platformName":"android",
#     "platformVersion":"10.0.0",
#     "deviceName":"66J5T19123004607",
#     "appPackage":"com.zhao.myreader",
#     "appActivity":"com.zhao.myreader.ui.home.MainActivity"
# }

#启动方法二,不需要包名和活动名 需要包的路径(电脑存放包的路径)
desired_caps={
    "platformName":"android",
    "platformVersion":"7.1.2",
    "deviceName":"emulator-5554",
    "app":r"C:\Users\admin\Desktop\1\dushuwu.apk" , #需要把app首先复制到Python中,再把路径放进来
    # "fullReset":True,#它在运行完整个脚本之后,会卸载该app ,默认为flase
    "noReset":False #它 在启动APP之前,会清除你app里面的数据,默认flase
}

driver=webdriver.Remote(command_executor="http://127.0.0.1:4723/wd/hub",desired_capabilities=desired_caps)
#需要页面数据加载完,我们再去对比数据,所以现在我们需要设置一个等待时间
#我们还需要设置一个页面渲染的等待时间 ,无法通过特定内容设置所以我们要来捕捉成为显示等待
#数据加载等待时间
driver.implicitly_wait(10)#隐性等待
# driver.wait_activity(activity="",timeout=10)#主动等待(等待某个activity的资源加载完,需要输入名称和加载时间)




# 例子一:
#定位元素书城
# 最初定位方式driver.find_element_by_accessibility_id("书城").click()
# 显性等待优化后:locator=("accessibility id","书城")
#再次进行优化代后
locator=(MobileBy.ACCESSIBILITY_ID,"书城")
WebDriverWait(driver,10).until(EC.presence_of_element_located(locator=locator)).click()
#例子二:
#定位列表所有书籍
# books=driver.find_elements_by_xpath(
# #     # '//androidx.recyclerview.widget.RecyclerView[@resource-id="com.zhao.myreader:id/rv_book_list"]/android.widget.LinearLayout'
# #     '//*[@resource-id="com.zhao.myreader:id/rv_book_list"]/android.widget.LinearLayout'
# # )
#优化成如下:
#定位列表所有书籍优化成显性等待
locator=(MobileBy.XPATH,'//*[@resource-id="com.zhao.myreader:id/rv_book_list"]/android.widget.LinearLayout')
books=WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located(locator))

'''
# b、随机获取一本书为验证点数据
'''
# 使用随机总数构建的方式,获取一个在规定范围内的随机数,作为元素列表的下标

suiji=random.randint(0,len(books)-1)
book=books[suiji] #随机的一本书

# shuming=book.find_element_by_id("com.zhao.myreader:id/tv_book_name").text#获取这本书的书名
locator = (MobileBy.ID, "com.zhao.myreader:id/tv_book_name");
shuming=WebDriverWait(book,10).until(EC.visibility_of_element_located(locator)).text

# miaoshu=book.find_element_by_id("com.zhao.myreader:id/tv_book_desc").text#获取这本书的简介
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_desc")
miaoshu=WebDriverWait(book,10).until(EC.visibility_of_element_located(locator)).text

# zuozhe=book.find_element_by_id("com.zhao.myreader:id/tv_book_author").text#获取这本书的作者
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_author")
zuozhe=WebDriverWait(book,10).until(EC.visibility_of_element_located(locator)).text
#获取章节名称
# 1、点击书,进入详情页
book.click()
#2、点击立即阅读
# driver.find_element_by_id("com.zhao.myreader:id/btn_read_book").click()
locator=(MobileBy.ID,"com.zhao.myreader:id/btn_read_book")
WebDriverWait(driver,10).until(EC.element_to_be_clickable(locator)).click()
#3、点击文章弹出选择框
# driver.find_element_by_id("	com.zhao.myreader:id/tv_content").click()
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_content")
WebDriverWait(driver,10).until(EC.element_to_be_clickable(locator)).click()
#4、点击目录,获取章节
# driver.find_element_by_id("	com.zhao.myreader:id/ll_chapter_list").click()
locator=(MobileBy.ID,"com.zhao.myreader:id/ll_chapter_list")
WebDriverWait(driver,10).until(EC.element_to_be_clickable(locator)).click()
#获取所有章节数据
# zhangjie=driver.find_elements_by_xpath('//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')
locator=(MobileBy.XPATH,'//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')
zhangjie=WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located(locator))
#保存所有章节的数据,方便数据对比

#初级
# cunc=list()
# for i in zhangjie:
#     i.find_element_by_id("com.zhao.myreader:id/tv_chapter_title") .text#获取这本书里面的某个章节
#升级:
cuncu=dict() #将章节的数据存储到字典里面
for index,element in enumerate(zhangjie):
    locator=(MobileBy.ID,"com.zhao.myreader:id/tv_chapter_title")
    cuncu.update({index:WebDriverWait(element,10).until(EC.visibility_of_element_located(locator)).text})

'''
# d、依照书名去搜索,返回到搜索书城去搜索需要返回2次
'''
driver.back()
driver.back()
# driver.find_element_by_id("com.zhao.myreader:id/iv_search").click()#点击搜索,优化后如下
locator=(MobileBy.ID,"com.zhao.myreader:id/iv_search")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).click()

# driver.find_element_by_id("com.zhao.myreader:id/et_search_key").send_keys(shuming),优化后如下
locator=(MobileBy.ID,"com.zhao.myreader:id/et_search_key")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).send_keys(shuming)

# driver.find_element_by_id("com.zhao.myreader:id/tv_search_conform").click()#点击搜索页的搜索,优化后如下
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_search_conform")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).click()

#获取搜索出来的所有相关书籍
locator=(MobileBy.XPATH,'//*[@resource-id="com.zhao.myreader:id/lv_search_books_list"]/android.widget.LinearLayout')
search_books=WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located(locator))

#遍历搜索的书籍
search_index=None
for i in search_books:
    locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_name")
    bn=WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).text
    if shuming==bn:
        search_index=search_books.index(i)
if search_index is None:
    raise ValueError(f"没有找到:{shuming}")
else:
    search_book=search_books[search_index]
#搜索框的书籍,获取这本书的
# search_shuming=book.find_element_by_id("com.zhao.myreader:id/tv_book_name").text#获取这本书的书名
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_name")
search_shuming=WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).text

# search_miaoshu=book.find_element_by_id("com.zhao.myreader:id/tv_book_desc").text#获取这本书的简介
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_desc")
search_miaoshu=WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).text

# search_zuozhe=book.find_element_by_id("com.zhao.myreader:id/tv_book_author").text#获取这本书的作者
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_book_author")
search_zuozhe=WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).text


#点击搜索框的这本书进入详情页
search_book.click()
#点击立即阅读
locator=(MobileBy.ID,"com.zhao.myreader:id/btn_read_book")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).click()

#点击文章弹出选择框
# driver.find_element_by_id("	com.zhao.myreader:id/tv_content").click()
locator=(MobileBy.ID,"com.zhao.myreader:id/tv_content")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).click()
#点击目录,获取章节
locator=(MobileBy.ID,"com.zhao.myreader:id/ll_chapter_list")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(locator)).click()
# driver.find_element_by_id("	com.zhao.myreader:id/ll_chapter_list").click()
#获取所有章节数据
locator=(MobileBy.XPATH,'//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')
search_zhangjie=WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located(locator))
# search_zhangjie=driver.find_elements_by_xpath('//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')
#存储搜索页的数据
search_cuncu=dict()
for search_index,search_element in enumerate(search_zhangjie):
    locator=(MobileBy.ID,"com.zhao.myreader:id/tv_chapter_title")
    # search_cuncu.update({search_index:search_element.find_element_by_id("com.zhao.myreader:id/tv_chapter_title")})
    search_cuncu.update(
        {search_index:WebDriverWait(search_element,10).until(EC.visibility_of_element_located(locator)).text})
#获取了书城的书和搜索页搜索出来的书后,我们再来判断同名书籍-搜索页的书和书城的书是否一致
if shuming==search_shuming and miaoshu==search_miaoshu and zuozhe==search_zuozhe and cuncu==search_cuncu:
    print("通过搜索功能搜索出的书籍与书城中获取的书籍是相同的")
else:
    print("验证失败")
    print(f"shuming:{shuming}")
    print(f"search_shuming:{search_shuming}")
    print(f"zuozhe:{zuozhe}")
    print(f"search_zuozhe:{search_zuozhe}")
    print(f"miaoshu:{miaoshu}")
    print(f"search_miaoshu:{search_miaoshu}")
    print(f"zhangjie:{zhangjie}")
    print(f"search_zhangjie:{search_zhangjie}")
driver.quit()

强制等待-time.sleep(2)

点击是地方加上等待时间即可

driver.find_element_by_accessibility_id("书城").click()
time.sleep(2)

命令等待

newCommandTimeout

封装等待方式

# -*- coding: utf-8 -*-
# author: 华测-长风老师
"""

验证通过搜索功能搜索的书籍,与从书城中获取的书籍是相同的;

首先,我们要完成 从书城中获取数据,并获取需要验证的数据;验证的数据不需要太全,但是也不能太少;

比如,验证数据,我们可以选择为:
1、书籍名称
2、数据的作者信息
3、数据的段落信息
4、数据的描述信息

"""
import random

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from appium.webdriver.common.mobileby import MobileBy
from appium import webdriver

# 首先连接设备


desired_capability = {
    "platformName": "android",
    "platformVersion": '10.0.0',
    "deviceName": 'CUYDU19625011655',
    "app": "/Volumes/huace/APP自动化测试课程/class04/课程脚本/pythonProject/dushuwu.apk",
    "noReset": True,
    # "fullReset": True,
}

driver = webdriver.Remote(command_executor="http://localhost:4723/wd/hub", desired_capabilities=desired_capability)


def wait_ele_clickable(driver, by, value):
    locator = (by, value)
    return WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator))


def wait_eles_visibility(driver, by, value):
    locator = (by, value)
    return WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located(locator))


def wait_ele_visibility(driver, by, value):
    locator = (by, value)
    return WebDriverWait(driver, 10).until(EC.visibility_of_element_located(locator))


wait_ele_clickable(driver, MobileBy.ACCESSIBILITY_ID, "书城").click()

book_elements = wait_eles_visibility(driver, MobileBy.XPATH,
                                     '//*[@resource-id="com.zhao.myreader:id/rv_book_list"]/android.widget.LinearLayout')

# 构建一个随机下标
rand_index = random.randint(0, len(book_elements) - 1)

book_element = book_elements[rand_index]

book_name = wait_ele_visibility(book_element, MobileBy.ID, "com.zhao.myreader:id/tv_book_name").text

book_desc = wait_ele_visibility(book_element, MobileBy.ID, "com.zhao.myreader:id/tv_book_desc").text

book_author = wait_ele_visibility(book_element, MobileBy.ID, "com.zhao.myreader:id/tv_book_author").text

book_element.click()

wait_ele_clickable(driver, MobileBy.ID, "com.zhao.myreader:id/btn_read_book").click()

wait_ele_clickable(driver, MobileBy.ID, "com.zhao.myreader:id/tv_content").click()

wait_ele_clickable(driver, MobileBy.ID, "com.zhao.myreader:id/ll_chapter_list").click()

chapter_elements = wait_eles_visibility(driver, MobileBy.XPATH,
                                        '//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')

book_chapters = dict()

for index, value in enumerate(chapter_elements):
    book_chapters.update({index: wait_ele_visibility(value, MobileBy.ID, 'com.zhao.myreader:id/tv_chapter_title').text})

driver.back()
driver.back()

wait_ele_clickable(driver, MobileBy.ID, 'com.zhao.myreader:id/iv_search').click()

locator = (MobileBy.ID, 'com.zhao.myreader:id/et_search_key')

wait_ele_visibility(driver, *locator).send_keys(book_name)

locator = (MobileBy.ID, 'com.zhao.myreader:id/tv_search_conform')

wait_ele_clickable(driver, *locator).click()

locator = (MobileBy.XPATH, '//*[@resource-id="com.zhao.myreader:id/lv_search_books_list"]/android.widget.LinearLayout')

search_books = wait_eles_visibility(driver, *locator)

search_index = None
for i in search_books:
    locator = (MobileBy.ID, "com.zhao.myreader:id/tv_book_name")
    bn = wait_ele_visibility(i, *locator).text
    if book_name == bn:
        search_index = search_books.index(i)

if search_index is None:
    raise ValueError(f"没有找到: {book_name} 这本书")

else:

    search_book = search_books[search_index]

    locator = (MobileBy.ID, "com.zhao.myreader:id/tv_book_name")
    search_book_name = wait_ele_visibility(search_book, *locator).text

    locator = (MobileBy.ID, "com.zhao.myreader:id/tv_book_desc")
    search_book_desc = wait_ele_visibility(search_book, *locator).text

    locator = (MobileBy.ID, "com.zhao.myreader:id/tv_book_author")
    search_book_author = wait_ele_visibility(search_book, *locator).text

    search_book_chapters = dict()

    search_book.click()

    locator = (MobileBy.ID, "com.zhao.myreader:id/btn_read_book")

    wait_ele_clickable(driver, *locator).click()

    locator = (MobileBy.ID, "com.zhao.myreader:id/tv_content")

    wait_ele_clickable(driver, *locator).click()

    locator = (MobileBy.ID, "com.zhao.myreader:id/ll_chapter_list")

    wait_ele_clickable(driver, *locator).click()

    locator = (MobileBy.XPATH, '//*[@resource-id="com.zhao.myreader:id/lv_chapter_list"]/android.widget.LinearLayout')

    search_chapter_elements = wait_eles_visibility(driver, *locator)

    for index, value in enumerate(search_chapter_elements):
        locator = (MobileBy.ID, "com.zhao.myreader:id/tv_chapter_title")

        search_book_chapters.update(
            {index: wait_ele_visibility(value, *locator).text})

    if book_name == search_book_name and book_desc == search_book_desc and book_author == search_book_author and book_chapters == search_book_chapters:
        print("通过搜索功能搜索的书籍,与从书城中获取的书籍是相同的")
    else:
        print("验证失败")
        print(f"book_name:{book_name}")
        print(f"search_book_name:{search_book_name}")
        print(f"book_desc:{book_desc}")
        print(f"search_book_desc:{search_book_desc}")
        print(f"book_author:{book_author}")
        print(f"search_book_author:{search_book_author}")
        print(f"book_chapters:{book_chapters}")
        print(f"search_book_chapters:{search_book_chapters}")

    driver.quit()

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:30:46  更:2022-04-15 00:31:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年4日历 -2025/4/4 21:56:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码