目录

  • appium-录制用例
    • 获取包名和activity
    • 录制步骤
      • (1)启动appium客户端,默认启动地址 http://127.0.0.1:4723/wd/hub
      • (2)file>New Session Window
      • (3)配置设备信息、包名等,点【Start Session】
      • (4)录制脚本
    • 代码
    • 报错
  • Capability设置
    • 重置策略
    • 获取安卓udid
  • 手机设置
    • 开启开发者模式
    • 开启手机指针位置
  • 定位工具:uiautomatorviewer.bat
  • 元素定位
    • 常用定位方式
    • 元素常用方法
      • 代码
    • TouchActions
      • 代码
    • 特殊控件toast定位
      • 定位
      • 代码
    • uiautomator定位
      • 常用表达式
      • 组合定位:
      • 父子关系定位:
      • 滚动页面查找元素
      • 代码
  • 踩坑
    • ui automator识别模拟器为横屏
    • Selenium error: Could not parse UiSelector argument: 'com.xueqiu.android:id/tv_search' is not a stringCall to '10' failed

appium-录制用例

获取包名和activity

windows系统
adb shell dumpsys activity |find “mFocusedActivity” 获取当前activity

C:\Users\Administrator>adb shell dumpsys activity |find "mFocusedActivity"mFocusedActivity: ActivityRecord{10828b7 u0 com.xueqiu.android/.common.MainActivity t11}

adb shell dumpsys window | findstr mCurrentFocus 获取当前activity

C:\Users\Administrator>adb shell dumpsys window | findstr mCurrentFocusmCurrentFocus=Window{26c290 u0 com.xueqiu.android/com.xueqiu.android.common.MainActivity}

录制步骤

(1)启动appium客户端,默认启动地址 http://127.0.0.1:4723/wd/hub

(2)file>New Session Window

(3)配置设备信息、包名等,点【Start Session】

{
“platformName”: “android”,
“deviceName”: “Huawei Mate30”,
“appPackage”: “com.xueqiu.android”,
“appActivity”: “.view.WelcomeActivityAlias”,
“noReset”: “True”
}

(4)录制脚本

  • 点【录制】
  • 点【选择元素】
  • 选择元素:点左边的输入框
  • 点右边的【Tap】即点击输入框操作
  • 选择元素:点坐标的输入框
  • 点右边的【Send Keys】,输入文本,即向左边的输入框输入搜索关键词
  • Recoder选择【Python】语言
  • 结束【录制】
  • 复制录制脚本

    动图

代码


# pip install appium-python-client
from appium import webdriver
import time
descrip_cap = {"platformName": "android","deviceName": "Huawei Mate30","appPackage": "com.xueqiu.android","appActivity": ".view.WelcomeActivityAlias","noReset": "True"
}driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",descrip_cap)
driver.implicitly_wait(10)
#####################复制录制的脚本#############################
el1 = driver.find_element_by_id("com.xueqiu.android:id/tv_search")
el1.click()
el2 = driver.find_element_by_id("com.xueqiu.android:id/search_input_text")
el2.send_keys("alibaba")
el3 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.LinearLayout/androidx.recyclerview.widget.RecyclerView/android.widget.RelativeLayout[1]/android.widget.LinearLayout/android.widget.TextView[1]")
el3.click()
el4 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.LinearLayout/androidx.viewpager.widget.ViewPager/android.widget.RelativeLayout/android.view.ViewGroup/androidx.recyclerview.widget.RecyclerView/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.FrameLayout[1]/android.widget.RelativeLayout/android.widget.LinearLayout[1]/android.widget.TextView")
el4.click()
#####################复制录制的脚本#############################
time.sleep(5)
driver.quit()

运行效果:

报错

An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: 'Command 'D\:\\adt-bundle-windows-x86_64-20140702\\sdk\\platform-tools\\adb.exe -P 5037 -s d270ac3a shell pm clear com.xueqiu.android' exited with code 255'; Stderr: 'Security exception: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android    java.lang.SecurityException: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android  at com.android.server.am.ActivityManagerService.clearApplicationUserData(ActivityManagerService.java:7695)  at com.android.server.pm.PackageManagerShellCommand.runClear(PackageManagerShellCommand.java:1632)  at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:204)  at android.os.ShellCommand.exec(ShellCommand.java:103)  at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:24667)  at android.os.Binder.shellCommand(Binder.java:634)  at android.os.Binder.onTransact(Binder.java:532)  at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:3152)  at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:4970)  at android.os.Binder.execTransact(Binder.java:731)'; Code: '255'

Security exception: PID 26038 does not have permission android.permission.CLEAR_APP_USER_DATA to clear data of package com.xueqiu.android
原因:
安卓手机未开启OEM解锁
解决:
设置>开发者选项>OEM解锁,改为开启

Capability设置

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

Capability Description Values
automationName automation引擎 Appium (default), or UiAutomator2, Espresso, or UiAutomator1 for Android, or XCUITest or Instruments for iOS, or YouiEngine for application built with You.i Engine
app app地址 /abs/path/to/my.apk or http://myapp.com/app.ipa
platformName 手机使用的操作系统 iOS, Android, or FirefoxOS
platformVersion 操作系统版本 e.g., 7.1, 4.4
deviceName 设备名称 iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android Emulator, Galaxy S4
udid 设备唯一标识符 e.g. 1ae203187fc012g
noReset 不重置app状态 true, false
fullReset 重置app true, false
dontStopAppOnReset 在使用adb启动应用程序之前,不会停止测试应用程序的进程。如果被测试的应用程序是由另一个锚应用程序创建的,设置为false,则允许锚应用程序的进程在使用adb启动测试应用程序期间仍然是活动的。换句话说,当dontStopAppOnReset设置为true时,我们将不会在adb shell am start调用中包含-S标志。省略此功能或将其设置为false后,我们将包含-S标志。默认false true, false
newCommandTimeout 在假定客户机退出并结束会话之前,Appium等待来客户机新命令的时间(以秒为单位) e.g 60单位秒
appActivity【安卓】 启动的Android活动(页面)的活动(页面)名 MainActivity, .Settings
appPackage【安卓】 apk包名 com.example.android.myApp, com.android.settings
dontStopAppOnReset【安卓】 在adb启动应用程序之前,不会停止测试应用程序的进程 true or false
skipDeviceInitialization【安卓】 跳过设备初始化,包括.安装和运行设置应用程序或设置权限。可用于提高启动性能 true or false
unicodeKeyboard【安卓】 支持Unicode 输入, 默认为false;切换非英文输入 true or false
resetKeyboard【安卓】 将键盘重置为其原始状态为false true or false
autoGrantPermissions【安卓】 在安装时自动授权app所需要的权限,默认为fasle。如果noReset为 true,此配置不生效。 true or false
skipDeviceInitialization【安卓】 跳过设备初始化,包括安装和运行设置应用程序或设置权限。可用于提高启动性能,设备已用于自动化,并为下一次自动化做好准备。默认为false true or false
skipUnlock【安卓】 在会话创建期间跳过解锁。默认值为false true or false
skipLogcatCapture【安卓】 跳过捕捉logcat日志。它可能会提高性能,比如网络。日志相关的命令将无法工作。默认值为false。 true or false
systemPort【安卓】 systemPort用于连接到appium-uiautomator2-server或appium-espresso-driver。默认值一般是8200,对于appium-uiautomator2-server,从8200到8299选择一个端口,对于appium- espreso -driver,从8300到8399选择8300。并行运行测试时,必须调整端口以避免冲突。 e.g., 8201
ignoreUnimportantViews【安卓】 调用setCompressedLayoutHierarchy()。忽略一些元素提高运行速度。被忽略的元素将无法找到。默认false true or false

重置策略

获取安卓udid

C:\Users\Administrator>adb devices
List of devices attached
eaa66aa37d14    unauthorized
127.0.0.1:62001 device

模拟器
"udid":"127.0.0.1:62001"

真机
"udid":"eaa66aa37d14"

手机设置

开启开发者模式

(1)设置>关于手机>连续点击版本号5次以上

(2)设置中,已经出现【开发者选项】

开启手机指针位置

开发者选项—>指针位置,设为开启状态。开启后,顶部会有指针移动坐标,可定位屏幕上的元素的坐标。

定位工具:uiautomatorviewer.bat

元素定位

常用定位方式

       driver.find_element_by_id(resource-id)driver.find_element_by_accessibility_id(content-desc)driver.find_element_by_xpath("//*")
  • id定位取 resource-id的值
  • accessibility_id定位取 content-desc的值
  • xpath定位建议组合定位

元素常用方法

方法 释义
element.click() 点击
element.send_keys(text) 输入文本
element.se_value(value) 设置元素的值
element.clear() 清除操作
element.is_displayed() 判断元素是否可见,返回true或false
element.is_enabled() 判断元素是否可用,返回true或false
element.is_selected() 判断元素是否被选中,返回true或false
element.get_attribute(name) 获取属性值
element.text 获取元素文本
element.location 获取元素坐标.e.g.{“y”:19,“x”:20}
element.size 获取元素尺寸(高和宽)e.g.{“width”:50,“height”:42}

代码

# pip install appium-python-client
from appium import webdriver
import timeclass TestXueQiu:def setup(self):descrip_cap = {"platformName": "android","deviceName": "Huawei Mate30","appPackage": "com.xueqiu.android","appActivity": ".view.WelcomeActivityAlias","noReset": "True","unicodeKeyboard":"True","resetKeyboard":"True",}self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)self.driver.implicitly_wait(10)def teardown(self):time.sleep(3)self.driver.quit()def test_xueqiu(self):# 定位、点击搜索框el1 = self.driver.find_element_by_id("com.xueqiu.android:id/tv_search")el1.click()# 输入搜索关键词el2 = self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text")el2.send_keys("阿里巴巴")#点击搜索到的词条el3 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']")el3.click()# 点击阿里巴巴,进入股票页面el4 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/stockName' and @text='阿里巴巴']")el4.click()# 获取当前股价el5 = self.driver.find_element_by_id("com.xueqiu.android:id/stock_current_price")print("阿里巴巴当前股价为:%s"% str(el5.text))# 判断阿里巴巴股价是否大于200assert float(el5.text) > 200

TouchActions

文档:
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md

常用方法:

方法 释义
press 按住
release 释放
moveTo 移动至
tap 点击
wait 等待,单位为ms
longPress 长按
perform 执行

TouchAction

TouchAction().press(el0).moveTo(el1).release()

MultiTouch同时按住多个元素

action0 = TouchAction().tap(el)
action1 = TouchAction().tap(el)
MultiAction().add(action0).add(action1).perform()

滚动

driver.execute_script("mobile: scroll", {"direction": "down"})

代码

# pip install appium-python-client
from appium import webdriver
import timefrom appium.webdriver.common.touch_action import TouchActionclass TestTouchAction:def setup(self):descrip_cap = {"platformName": "android","deviceName": "Huawei Mate30","appPackage": "cn.kmob.screenfingermovelock","appActivity": "com.samsung.ui.FlashActivity","noReset": "True",}self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)self.driver.implicitly_wait(10)def teardown(self):time.sleep(3)self.driver.quit()def test_xueqiu(self):#点击开启手势密码el1 = self.driver.find_element_by_accessibility_id("手势密码锁")el1.click()# 绘制手势密码# 以下坐标试用 手机分辨率为540*960coordinate1 = (90,128)coordinate2 = (272,128)coordinate3 = (450,128)coordinate4 = (272,350)wait_time = 220 #单位为ms毫秒TouchAction(self.driver).press(x=coordinate1[0],y=coordinate1[1]).wait(wait_time)\.move_to(x=coordinate2[0],y=coordinate2[1]).wait(wait_time)\.move_to(x=coordinate3[0],y=coordinate3[1]).wait(wait_time)\.move_to(x=coordinate4[0],y=coordinate4[1]).wait(wait_time)\.release().perform()# 点击继续el2 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo")el2.click()# 再次绘制绘制手势密码TouchAction(self.driver).press(x=coordinate1[0], y=coordinate1[1]).wait(wait_time) \.move_to(x=coordinate2[0], y=coordinate2[1]).wait(wait_time) \.move_to(x=coordinate3[0], y=coordinate3[1]).wait(wait_time) \.move_to(x=coordinate4[0], y=coordinate4[1]).wait(wait_time) \.release().perform()# 点击确认el3 = self.driver.find_element_by_id("cn.kmob.screenfingermovelock:id/btnTwo")el3.click()

特殊控件toast定位

toast

  • 简短消息提示框
  • 根据设置的显示时间后自动消失
  • 系统级别控件。归属于系统settings。不在app内。

例如下图的“验证码已发送”提示语

定位

通过打印页面元素,可以看到toast元素

<android.widget.Toast index="1" package="com.android.settings" class="android.widget.Toast" text="验证码已发送" checkable="false" checked="false" clickable="false" enabled="false" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][0,0]" displayed="true" />

但是通过class="android.widget.Toast"无法定位到,因此使用Xpath通过文本定位

driver.find_element_by_xpath('//*[@text="验证码已发送"]')

注意:Capability设置需加上automationName,才可以定位到
“automationName”:“uiautomator2”

代码

# pip install appium-python-client
from appium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from appium.webdriver.common.mobileby import MobileByclass TestXueQiu:def setup(self):des_caps = {"platformName": "android","deviceName": "Huawei Mate30","appPackage": "com.xueqiu.android","appActivity": ".view.WelcomeActivityAlias","noReset": "True","unicodeKeyboard":"True","resetKeyboard":"True","automationName":"uiautomator2"}self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", des_caps)self.driver.implicitly_wait(10)def teardown(self):time.sleep(3)self.driver.quit()def test_toast(self):# 点击【我的】self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/tab_name' and @text='我的']").click()# 点击【手机号】登录self.driver.find_element_by_id('com.xueqiu.android:id/tv_login_phone').click()# 输入手机号码self.driver.find_element_by_id('com.xueqiu.android:id/register_phone_number').send_keys("18000000000")#任意填个手机号码# 点击【发送验证码】self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').click()# 等待toast元素加载locator = (MobileBy.XPATH,'//*[@text="验证码已发送"]')WebDriverWait(self.driver,30).until(expected_conditions.presence_of_element_located(locator))# # 打印当前页面元素树print(self.driver.page_source)# toast元素# <android.widget.Toast index="1" package="com.android.settings" class="android.widget.Toast" text="验证码已发送" checkable="false" checked="false" clickable="false" enabled="false" focusable="false" focused="false" long-clickable="false" password="false" scrollable="false" selected="false" bounds="[0,0][0,0]" displayed="true" /># 等待toast元素消失WebDriverWait(self.driver, 30).until_not(expected_conditions.presence_of_element_located(locator))# 定位"重新获取"验证码按钮,获取文案text = self.driver.find_element_by_id('com.xueqiu.android:id/register_code_text').textassert "重新获取" in text

uiautomator定位

https://developer.android.com/reference/android/support/test/uiautomator/UiSelector.html

uiautomator是安卓的工作引擎,速度快,但表达式书写复杂。

常用表达式

表达式
new UiSelector().reaourceId(“id”) 通过id定位
new UiSelector().className(“className”) 通过className定位
new UiSelector().descriptioon(“content-desc”) 通过content-desc定位
new UiSelector().text(“text”) 通过文本定位
new UiSelector().textContains(“包含文本”) 通过包含文本定位
new UiSelector().textStartsWith(“以text开头”) 匹配以text开头的元素
new UiSelector().textMatches(“正则表达式”) 通过正则表达式匹配文本
childSelector() 父子关系定位
fromParent() 兄弟关系定位

组合定位:

driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")')

父子关系定位:

driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))')

滚动页面查找元素

 self.driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).''instance(0)).scrollIntoView(new UiSelector().textContains("财经").''instance(0))').click()

代码

# pip install appium-python-client
from appium import webdriver
import timeclass TestXueQiu:def setup(self):descrip_cap = {"platformName": "android","deviceName": "Huawei Mate30","appPackage": "com.xueqiu.android","appActivity": ".view.WelcomeActivityAlias","noReset": "True","unicodeKeyboard":"True","resetKeyboard":"True"}self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", descrip_cap)self.driver.implicitly_wait(10)def teardown(self):time.sleep(3)self.driver.quit()def test_check_alibaba(self):# 定位、点击搜索框# el1 = self.driver.find_element_by_id("com.xueqiu.android:id/tv_search")# resourceId("com.xueqiu.android:id/tv_search")el1 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tv_search")')el1.click()# 输入搜索关键词# el2 = self.driver.find_element_by_id("com.xueqiu.android:id/search_input_text")el2 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/search_input_text")')el2.send_keys("阿里巴巴")#点击搜索到的词条# Xpath定位# el3 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/name' and @text='阿里巴巴']")el3 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/name").text("阿里巴巴")')el3.click()# 点击阿里巴巴,进入股票页面# Xpath定位# el4 = self.driver.find_element_by_xpath("//*[@resource-id='com.xueqiu.android:id/stockName' and @text='阿里巴巴']")# el4 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stockName").text("阿里巴巴")')# 通过搜索结果列表框定位其儿子节点中text为“阿里巴巴”的元素el4 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/ll_stock_result_view").childSelector(text("阿里巴巴"))')el4.click()# 获取当前股价# el5 = self.driver.find_element_by_id("com.xueqiu.android:id/stock_current_price")el5 = self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/stock_current_price")')print("阿里巴巴当前股价为:%s"% str(el5.text))# 判断阿里巴巴股价是否大于200assert float(el5.text) > 200def test_scroll_to_article(self):time.sleep(1)# 滚动匹配包含"财经"的文本,并点击self.driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).''instance(0)).scrollIntoView(new UiSelector().textContains("财经").''instance(0))').click()

踩坑

ui automator识别模拟器为横屏


原因:
ui automator识别通过分辨率识别为横屏

解决:
设置模拟器分辨率

Selenium error: Could not parse UiSelector argument: ‘com.xueqiu.android:id/tv_search’ is not a stringCall to ‘10’ failed

Call to ‘10’ failed
[elements("-android uiautomator",“new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’)”)] Error response status: 9, , UnknownCommand - The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. Selenium error: Could not parse UiSelector argument: ‘com.xueqiu.android:id/tv_search’ is not a string

原因:
定位表达式中使用了单引号
new UiSelector().resourceId(‘com.xueqiu.android:id/tv_search’)

解决:
定位表达式中使用了双引号
new UiSelector().resourceId(“com.xueqiu.android:id/tv_search”)

appium(2)简单的demo、元素定位相关推荐

  1. python元素定位id和name_python中通过selenium简单操作及元素定位知识点总结

    浏览器的简单操作 # 导入webdriver模块 # 创建driver对象,指定Chrome浏览器 driver = webdriver.Chrome() # 窗口最大化 driver.maximiz ...

  2. Appium移动端自动化测试之元素定位(三)

    1.name定位 driver.find_element_by_id('com.shanjian.originaldesign:id/edit_Tel').send_keys('15817252876 ...

  3. appium微信公众号分类元素定位方法

    appium自动化遇到定位分类中的元素,开始以为切换分类是一个新的页面,一直定位元素都提示元素不可交互,原因是实际上三个分类中的元素都是一个前端页面展示,你去切换分类定位第二个分类里元素,实际上定位的 ...

  4. Appium+PythonUI自动化测试之uiautomatorviewer和Inspector元素定位

    一.uiautomatorviewer uiautomatorviewer是android-sdk自带的一个元素定位工具,非常简单好用,使用uiautomatorviewer,你可以检查一个应用的UI ...

  5. Appium 自动化测试元素定位工具使用

    简介     前面环境基本都搭建好了,相关的知识也准备的差不多了,那么我们就开始下一步元素定位,元素定位首先需要知道使用哪些元素定位工具,本文讲解常见的元素定位工具uiautomatorviewer和 ...

  6. Appium+python自动化(九)- 定位元素工具(义结金兰的两位异性兄弟)(超详解)...

    简介 环境搭建好了,其他方面的知识也准备的差不多了,那么我们就开始下一步元素定位,元素定位宏哥主要介绍如何使用uiautomatorviewer,通过定位到页面上的元素,然后进行相应的点击等操作. 此 ...

  7. [Appium] App自动化-元素定位

    [Appium] App自动化-元素定位及工具 一.元素定位工具简介 Web自动化是通过浏览器自带的F12键进行元素定位,但是App自动化支持三大定位工具(UIAutomatorView/Appium ...

  8. Appium(三)常用的8种元素定位方式之 id、name、class、相对定位

    其实APP自动化测试的元素定位方式和Web自动化测试元素定位方式大体相同,无论是APP还是Web自动化测试,最重要的一个环节就是获取元素的定位,只有准确的定位到了元素才能进行相关元素的操作,而Appi ...

  9. 【资料补充】元素定位和定位辅助工具

    Web页面组成-代码 <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...

最新文章

  1. css:z-index
  2. 微服务时代组件化和服务化的抉择
  3. 互联网+大赛作品_“颂中国力量 绘美好梦想”全市中小学生互联网+书画大赛作品展示(二十六)...
  4. 赶上直播电商、在线教育、小程序直播的风口 腾讯音视频解决方案助力
  5. 李宏毅线性代数笔记 10: PageRank
  6. maven工程如何引用css和js文件
  7. IOT(Index Organized Table)
  8. pymysql安装_centos7.6 安装openstack stein组件之四
  9. ubuntu 14.04 配置 java 环境
  10. Android Studio 插件——《阿里巴巴 Java 开发规约》的扫描插件
  11. 微软官方出的各种dll丢失的修复工具
  12. 这些年,我身边的那些人和事
  13. 笔记本计算机摄像头怎么打开,手把手教你笔记本内置摄像头打不开解决方法
  14. 笔记工具:幕布 简要使用教程
  15. 我的世界服务器修改高度放水,我的世界:水不够用?学会这4种方法,教你一桶水造无限水...
  16. 高可用集群下的负载均衡(6):haproxy实现访问不同资源的负载均衡(日志、监控、acl访问控制的配置)
  17. Java实现印刷体转手写体—妈妈再也不用担心我被罚抄作业了
  18. Iso中查看Windows版本
  19. 蘑菇丁工学云打卡教程
  20. Stata做空间杜宾模型、莫兰指数等操作

热门文章

  1. 【记录贴!】记录调试nerf-pytorch踩过的坑
  2. thumbnailator图片压缩和碰见的问题修复
  3. 最全最佳的wordpress插件汇总推荐-php
  4. Java 从键盘输入一个字符串,统计某个字符的个数
  5. 易联云打印机 php
  6. android+最新手机,最新Android手机性能榜单:骁龙845+8G的它只排第三
  7. ROC原理介绍及利用python实现二分类和多分类的ROC曲线
  8. Linux学习4 yum仓库 编译安装 sed基本用法
  9. C++嵌入汇编语言计算有符号数组的平均值
  10. 安装和使用spacemacs