GVKun编程网logo

数据库 – OS X App.哪种方式是存储数据的最佳方式?(数据库中数据存储方式)

1

本文将分享数据库–OSXApp.哪种方式是存储数据的最佳方式?的详细内容,并且还将对数据库中数据存储方式进行详尽解释,此外,我们还将为大家带来关于41-数据库-pymysql41-数据库-pymysq

本文将分享数据库 – OS X App.哪种方式是存储数据的最佳方式?的详细内容,并且还将对数据库中数据存储方式进行详尽解释,此外,我们还将为大家带来关于41 - 数据库-pymysql41 - 数据库-pymysql-DBUtils、ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j、angular – ng new hello错误:路径“/app/app.module.ts”不存在.路径“/app/app.module.ts”不存在、APP 自动化 01 - 基础操作 API-UIautomatorviewer-APP 定位 - 元素等待 - APP 模拟手势高级操作的相关知识,希望对你有所帮助。

本文目录一览:

数据库 – OS X App.哪种方式是存储数据的最佳方式?(数据库中数据存储方式)

数据库 – OS X App.哪种方式是存储数据的最佳方式?(数据库中数据存储方式)

在os x app中,这是存储数百个用户记录的最佳方式,每条记录包含大量信息?

我知道我可以使用CoreData,sqlite,Realm,plist或其他解决方案.
哪个是最兼容的(我认为例如用于Web使用)和干净/轻/快的方法/数据库类型来存储数据?

谢谢

解决方法

Core Data由Apple编写,用于基于 Cocoa的应用程序.它已经包含在操作系统中,已经有10年的发展历史,已经在应用程序商店中的数十万个应用程序中使用.

使用第三方库存在巨大的风险.

我总是建议在iOS和OS X上使用Core Data,因为它是由Apple编写的,有一个完全支持的开发团队,并且是一个成熟的代码库.

使用原始sqlite是可能的,但是您将无法获得与Core Data相同的性能优势.

Realm专注于错误的事情.他们的数据迁移系统很可怕,当他们需要关注整体情况时,他们会关注原始速度.他们可能会定位移动广告,但我不同意他们的目标.

对于任何数据库系统来说,数百条记录并不难.当你在一台设备上获得数以万计的记录时,由于内存压力,许多记录开始下降(即使在OS X上).

核心数据旨在帮助解决内存压力.我不知道任何第三方框架会这样做.

41 - 数据库-pymysql41 - 数据库-pymysql-DBUtils

41 - 数据库-pymysql41 - 数据库-pymysql-DBUtils

[toc]

1 Python操作数据库

        Python 提供了程序的DB-API,支持众多数据库的操作。由于目前使用最多的数据库为MySQL,所以我们这里以Python操作MySQL为例子,同时也因为有成熟的API,所以我们不必去关注使用什么数据,因为操作逻辑和方法是相同的。

2 安装模块

        Python 程序想要操作数据库,首先需要安装 模块 来进行操作,Python 2 中流行的模块为 MySQLdb,而该模块在Python 3 中将被废弃,而使用PyMySQL,这里以PyMySQL模块为例。下面使用pip命令安装PyMSQL模块

pip3 install pymysql

如果没有pip3命令那么需要确认环境变量是否有添加,安装完毕后测试是否安装完毕。

lidaxindeMacBook-Pro:~ DahlHin$ python3
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pymysql
>>>
# 如果没有报错,则表示安装成功

3 基本使用

        首先我们需要手动安装一个MySQL数据库,这里不再赘述,参考博文:http://www.cnblogs.com/dachenzi/articles/7159510.html

连接数据库并执行sql语句的一般流程是:

  1. 建立连接
  2. 获取游标(创建)
  3. 执行SQL语句
  4. 提交事务
  5. 释放资源

对应到代码上的逻辑为:

  1. 导入相应的Python模块
  2. 使用connect函数连接数据库,并返回一个Connection对象
  3. 通过Connection对象的cursor方法,返回一个Cursor对象
  4. 通过Cursor对象的execute方法执行SQL语句
  5. 如果执行的是查询语句,通过Cursor对象的fetchall语句获取返回结果
  6. 调用Cursor对象的close关闭Cursor
  7. 调用Connection对象的close方法关闭数据库连接

3.1 创建一个连接

使用pymysql.connect方法来连接数据库

import pymysql
 
pymysql.connect(host=None, user=None, password="",
                 database=None, port=0, unix_socket=None,
                 charset=''''......)

主要的参数有:

  • host:表示连接的数据库的地址
  • user:表示连接使用的用户
  • password:表示用户对应的密码
  • database:表示连接哪个库
  • port:表示数据库的端口
  • unix_socket:表示使用socket连接时,socket文件的路径
  • charset:表示连接使用的字符集 
  • read_default_file:读取mysql的配置文件中的配置进行连接

3.2 连接数据库

        调用connect函数,将创建一个数据库连接并得到一个Connection对象,Connection对象定义了很多的方法和异常。

host = ''10.0.0.13''
port = 3306
user = ''dahl''
password = ''123456''
database = ''test''

conn = pymysql.connect(host, user, password, database, port)
print(conn)  # <pymysql.connections.Connection object at 0x000001ABD3063550>
conn.ping()  # 没有返回值,无法连接会提示异常

这里conn就是一个Connection对象,它具有一下属性和方法:

  • begin:开始事务
  • commit:提交事务
  • rollback:回滚事务
  • cursor:返回一个Cursor对象
  • autocommit:设置事务是否自动提交
  • set_character_set:设置字符集编码
  • get_server_info:获取数据库版本信息
  • ping(reconnect=True): 测试数据库是否活着,reconnect表示断开与服务器连接后是否重连,连接关闭时抛出异常(一般用来测通断)

        在实际的编程过程中,一般不会直接调用begin、commit和rollback函数,而是通过上下文管理器实现事务的提交与回滚操作

3.3 游标

        游标是系统为用户开设的一个数据缓存区,存放SQL语句执行的结果,用户可以用SQL语句逐一从游标中获取记录,并赋值给变量,交由Python进一步处理。
        在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。
        正如前面我们使用Python对文件进行处理,那么游标就像我们打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。

3.3.1 利用游标操作数据库

在进行数据库的操作之前需要创建一个游标对象,来执行sql语句。

cursor = conn.cursor()

下面利用游标来执行sql语句:

import pymysql
 
def connect_mysql():
 
    db_config = {
        ''host'':''127.0.0.1'',
        ''port'':3306,
        ''user'':''root'',
        ''password'':''abc.123'',
        ''charset'':''utf8''
    }
 
    return  pymysql.connect(**db_config)
 
if __name__ == ''__main__'':
    conn = connect_mysql()
    cursor = conn.cursor()    # 创建游标
    sql = r" select user,host from mysql.user "  # 要执行的sql语句
    cursor.execute(sql)  # 交给 游标执行
    result = cursor.fetchall()  # 获取游标执行结果
    print(result)

3.3.2 事务管理

Connection对象包含如下三个方法用于事务管理:

  • begin:开始事务
  • commit:提交事务
  • rollback:回滚事务
import pymysql

def connect_mysql():
    db_config = {
        ''host'': ''10.0.0.13'',
        ''port'': 3306,
        ''user'': ''dahl'',
        ''password'': ''123456'',
        ''charset'': ''utf8''
    }

    return pymysql.connect(**db_config)


if __name__ == ''__main__'':
    conn = connect_mysql()
    cursor = conn.cursor()  # 创建游标

    conn.begin()
    sql = r"insert into test.student (id,name,age) VALUES (5,''dahl'',23)"  # 要执行的sql语句
    res = cursor.execute(sql)  # 交给 游标执行
    print(res)
    conn.commit()

这样使用是极其不安全的,因为sql语句有可能执行失败,当失败时,我们应该进行回滚

if __name__ == ''__main__'':
    conn = None 
    cursor = None
    try:
        conn = connect_mysql()
        cursor = conn.cursor()  # 创建游标
        sql = r"insert into test.student (id,name,age) VALUES (6,''dahl'',23)"  # 要执行的sql语句
        cursor.execute(sql)  # 交给 游标执行
        conn.commit()    # 提交事务
    except:
        conn.rollback()   # 当SQL语句执行失败时,回滚
    finally:
        if cursor:   
            cursor.close()    # 关闭游标
        if conn:
            conn.close()   # 关闭连接

3.3.3 执行SQL语句

用于执行SQL语句的两个方法为:

  • cursor.execute(sql):执行一条sql语句
  • executemany(sql,parser):执行多条语句
sql = r"select * from test.student" 
res = cursor.execute(sql)  

3.3.3.1 批量执行

executemany用于批量执行sql语句,

  • sql 为模板,c风格的占位符。
  • parser:为模板填充的数据(可迭代对象)
sql = r"insert into test.student (id,name,age) values (%s,''daxin'',20)"
cursor.executemany(sql,(7,8,9,))

3.3.3.2 SQL注入攻击

我们一般在程序中使用sql,可能会有如下代码:

# 接受用户id,然后拼接查询用户信息的SQL语句,然后查询数据库。
userid = 10 # 来源于程序
sql = ''select * from user where user_id = {}''.format(userid)

userid是可变的,比如通过客户端发来的request请求,直接拼接到查询字符串中。如果客户端传递的userid是 ''5 or 1=''呢

sql = ''select * from test.student where id = {}''.format(''5 or 1=1'')

此时真正在数据库中查询的sql语句就变成了

select * from test.student where id = 5 or 1=1

这条语句的where条件的函数含义是:当id等于5,或者1等于1时,列出所有匹配的字段,这样就轻松的查到了标准所有的数据!!!

永远不要相信客户端传来的数据是规范及安全的。

3.3.3.3 参数化查询

        cursor.execute(sql)方法还额外提供了一个args参数,用于进行参数化查询,它的类型可以为元组、列表、字典。如果查询字符串使用命名关键字(%(name)s),那么就必须使用字典进行传参。

sql = ''select * from test.student where id = %s''
cursor.execute(sql,args=(2,))

sql = ''select * from test.student where id = %(id)s''
cursor.execute(sql,args={''id'':2})

        我们说使用参数化查询,效率会高一点,为什么呢?因为SQL语句缓存。数据库一般会对SQL语句编译和缓存,编译只对SQL语句部分,所以参数中就算有SQL指令也不会被执行。编译过程,需要此法分析、语法分析、生成AST、优化、生成执行计划等过程,比较耗费资源。服务端会先查找是否是同一条语句进行了缓存,如果缓存未失效,则不需要再次编译,从而降低了编译的成本,降低了内存消耗。

可以认为SQL语句字符串就是一个key,如果使用拼接方案,每次发过去的SQL语句都不一样,都需要编译并缓存。大量查询的时候,首选使用参数化查询,以节省资源。

3.4 获取查询结果

Cursor类提供了三种查询结果集的方法:(返回值为元组,多个值为嵌套元组)

  • fetchone():获取一条
  • fetchmany(size=None):获取多条,当size为None时,返回一个包含一个元素的嵌套元组
  • fetchall():获取所有
sql = ''select * from test.student''
cursor.execute(sql)
print(cursor.fetchall())
print(cursor.fetchone())  # None
print(cursor.fetchmany(2))  # None

        fetch存在一个指针,fetchone一次,就读取结果集中的一个结果,如果fetchall,那么一次就会读取完所有的结果。可以通过调整这个指针来重复读取

  • cursor.rownumber: 返回当前行号,可以修改,支持 负数
  • cursor.rowcount: 返回总行数
sql = ''select * from test.student''
cursor.execute(sql)
print(cursor.fetchall())  # ((2, ''dahl'', 20), (3, ''dahl'', 21), (4, ''daxin'', 22), (5, ''dahl'', 23), (6, ''dahl'', 23), (7, ''daxin'', 20), (8, ''daxin'', 20), (9, ''daxin'', 20))
cursor.rownumber = 0
print(cursor.fetchone())  # (2, ''dahl'', 20)
print(cursor.fetchmany()) # ((3, ''dahl'', 21),)

fetch操作的是结果集,结果集是保存在客户端的,也就是说fetch的时候,查询已经结束了。

3.4.1 带列明的查询

        结果中不包含字段名,除非我们记住字段的顺序,不然很麻烦,那么下面来解决这个问题。

观察cursor原码,我们发现,它接受一个参数cursor,有一个参数是:DictCursor,查看源码得知,它是Cursor的Mixin子类。

def cursor(self, cursor=None):
    """
    Create a new cursor to execute queries with.

    :param cursor: The type of cursor to create; one of :py:class:`Cursor`,
        :py:class:`SSCursor`, :py:class:`DictCursor`, or :py:class:`SSDictCursor`.
        None means use Cursor.
    """
    if cursor:
        return cursor(self)
    return self.cursorclass(self)

观察DictCursor的原码,得知结果集会返回一个字典,一个字段名:值的结果,所以,只需要传入cursor参数即可

    from pymysql import cursors  # DictCursor存在与cursors模块中
    ... ... 
    cursor = conn.cursor(cursors.DictCursor) 
    sql = ''select * from test.student''
    cursor.execute(sql)
    print(cursor.fetchone())  # {''id'': 2, ''name'': ''dahl'', ''age'': 20}

3.5 上下文支持

Connection和Cursor类实现了__enter__和__exit__方法,所以它支持上下文管理。

  • Connection:进入时返回一个cursor,退出时如果有异常,则回滚,否则提交
  • Cursor: 进入时返回cursor本身,退出时,关闭cursor连接

所以利用上下文的特性,我们可以这样使用

import pymysql

def connect_mysql():
    db_config = {
        ''host'': ''10.0.0.13'',
        ''port'': 3306,
        ''user'': ''dahl'',
        ''password'': ''123456'',
        ''charset'': ''utf8''
    }

    return pymysql.connect(**db_config)

if __name__ == ''__main__'':
conn = connect_mysql()
with conn as cursor:
    sql = ''select * from student''
    cursor.execute(sql)
    print(cursor.fetchmany(2))

# conn的exit只是提交了,并没有关闭curosr
cursor.close()
conn.close()

如果要自动关闭cursor,可以进行如下改写

if __name__ == ''__main__'':
conn = connect_mysql()
with conn as cursor:
    with cursor   # curosr的exit会关闭cursor
        sql = ''select * from student''
        cursor.execute(sql)
        print(cursor.fetchmany(2))

conn.close()

多个 cursor共享一个 conn

4 DBUtils连接池

        在python编程中可以使用MySQLdb/pymysql等模块对数据库的连接及诸如查询/插入/更新等操作,但是每次连接mysql数据库请求时,都是独立的去请求访问,相当浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此,实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用的目的。

db_utils

连接池对性能的提升表现在:

  1. 在程序创建连接的时候,可以从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度
  2. 关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁地打开和关闭连接

        DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装。DBUtils来自Webware for Python。

DBUtils提供两种外部接口:

  • PersistentDB:提供线程专用的数据库连接,并自动管理连接。(为每一个线程创建一个)
  • PooledDB:提供线程间可共享的数据库连接,并自动管理连接。

为每个线程创建一个,资源消耗太大,所以我们常用的是PooledDB.

PooledDB常用的参数为:

  • creator=pymysql: 使用链接数据库的模块
  • maxconnections=6: 连接池允许的最大连接数,0和None表示不限制连接数
  • mincached=2: 初始化时,链接池中至少创建的空闲的链接,0表示不创建,如果空闲连接数小于这个数,pool会创建一个新的连接
  • maxcached=5: 链接池中最多闲置的链接,0和None不限制,如果空闲连接数大于这个数,pool会关闭空闲连接
  • maxshared=3: 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
  • blocking=True: 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
  • maxusage=None: 一个链接最多被重复使用的次数,None表示无限制
  • setsession=[]: 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
  • ping=0: ping MySQL服务端,检查是否服务可用。
    • 0 = None = never
    • 1 = default = whenever it is requested
    • 2 = when a cursor is created
    • 4 = when a query is executed
    • 7 = always
  • host=''127.0.0.1'',
  • port=3306,
  • user=''root'',
  • password=''123'',
  • database=''pooldb'',
  • charset=''utf8''

安装DBUtils

pip install DBUtils

示例代码:

import threading
import time
from DBUtils.PooledDB import PooledDB
import pymysql

POOL = PooledDB(
    creator=pymysql,
    maxconnections=6,
    mincached=2,
    maxcached=5,
    # maxshared=3,
    blocking=True,
    maxusage=None,
    setsession=[],
    ping=0,
    host=''10.0.0.13'',
    port=3306,
    user=''dahl'',
    password=''123456'',
    database=''test'',
    charset=''utf8''
)


def func():
    conn = POOL.connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    time.sleep(2)
    cursor.execute(''select * from employees'')
    res = cursor.fetchall()
    conn.close()
    print(threading.get_ident(), res)


if __name__ == ''__main__'':
    for i in range(10):
        threading.Thread(target=func).start()

ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

如何解决ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j

我正在Rails上执行此应用程序,页面加载正常,但在控制台中显示:

Started GET "/vendor/assets/stylesheets/bootstrap.min.css" for ::1 at 2020-08-17 09:09:51 -0500

Started GET "/vendor/assets/javascripts/bootstrap.min.js" for ::1 at 2020-08-17 09:09:51 -0500
ActionController::RoutingError (No route matches [GET] 
"/vendor/assets/stylesheets/bootstrap.min.css"):
ActionController::RoutingError (No route matches [GET] 
"/vendor/assets/javascripts/bootstrap.min.js"):

在我的供应商文件夹中,我同时拥有文件夹,javascript和样式表,并分别位于各自的bootsrtrap.min中。 即使在application.html.erb中,我也有以下内容:

  <link href="vendor/assets/stylesheets/bootstrap.min.css" rel="stylesheet">
  <%= csrf_Meta_tags %>
  <%= stylesheet_link_tag    ''application'',media: ''all'',''data-turbolinks-track'': ''reload'' %>
  <%= javascript_include_tag ''application'',''data-turbolinks-track'': ''reload'' %>

</head>
<body>

  <!-- Navigation -->
  <nav>
    <div>
      <ahref="#">Instagram Clone</a>
      <buttontype="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
        <span></span>
      </button>
      <divid="navbarResponsive">
        <ul>
          <li>
            <ahref="#">Home
              <span>(current)</span>
            </a>
          </li>
          <li>
            <ahref="#">About</a>
          </li>
          <li>
            <ahref="#">Services</a>
          </li>
          <li>
            <ahref="#">Contact</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <!-- Page Content -->
  <div>
    <div>
      <div>
        <%= yield %>
      </div>
    </div>
  </div>

  <!-- Bootstrap core JavaScript -->
  <!--<script src="vendor/jquery/jquery.slim.min.js"></script>-->
  <script src="vendor/assets/javascripts/bootstrap.min.js"></script>
    
</body>
</html>

在js和CSS这两个应用程序文件中,我都放置了“ require bootsrtrap.min”,即使该错误仍然出现在控制台中。 会是什么?

解决方法

RoR不使用目录作为文件夹结构指示。因为有资产装载者。您应该将5s或更少的css导入application.css中,并将js导入application.js中。并使用自己的助手添加捆绑文件:

1。用纱安装靴子

yarn add bootstrap @popperjs/core jquery

npm i bootstrap @popperjs/core jquery

栏位不超过5

2。在Assets Pipeline中导入文件

app / assets / stylesheets / application.css:

//...
require bootstrap/dist/css/bootstrap.min
//...

但是,如果需要,我建议使用SCSS并仅导入所需的样式。

app / assets / javascript / application.js:

//...
//= require jquery
//= require @popperjs/core
//= require bootstrap/dist/js/bootstrap.min
//...

3。在布局中导入资产

app / views / layout / application.html.erb:

<head>
...
  <%= stylesheet_link_tag ''application'',media: ''all'' %>
</head>
<body>
...
  <%= javascript_include_tag ''application'' %>
</body>

使用webpack滚动6

2。在application.scss和application.js中导入Bootstrap

app / javascript / stylesheets / application.scss:

//...
import ''bootstrap''
//...

app / javascript / packs / application.js:

import ''jquery''
import ''popper.js''
import ''bootstrap''
import ''../stylesheets/application''

3。在布局中导入捆绑包

<head>
...
  <%= stylesheet_pack_tag ''application'',media: ''all'',''data-turbolinks-track'': ''reload'' %>
  <%= javascript_pack_tag ''application'',''data-turbolinks-track'': ''reload'' %>
</head>

之后,您应该可以在所有应用程序中使用引导程序!

,

[解决方案]因此,在我的HTML(application.html.erb)内部,我有两个对js和css文件的调用:

<script src="assets/javascripts/bootstrap.min.js"></script>
  <%= javascript_include_tag ''application'',''data-turbolinks-track'': ''reload'' %>       
<link href="assets/stylesheets/bootstrap.min.css" rel="stylesheet">
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag    ''application'',''data-turbolinks-track'': 
  ''reload'' %>

正如您在上面看到的那样,在使用javascript的情况下,我有一个使用脚本的调用,而另一个使用了的调用,两者都造成了问题,所以您只需要评论一个,我就对该脚本进行评论对于我的java文件和CSS文件,一个。 像这样:

  <!--<link href="assets/stylesheets/bootstrap.min.css" rel="stylesheet">-->
    <!--<script src="assets/javascripts/bootstrap.min.js"></script>-->

对我来说,解决了这个问题,我真的尝试了所有事情,这就是解决方案哈哈。

angular – ng new hello错误:路径“/app/app.module.ts”不存在.路径“/app/app.module.ts”不存在

angular – ng new hello错误:路径“/app/app.module.ts”不存在.路径“/app/app.module.ts”不存在

我在角度创建新项目时面临问题.
当我运行新的myapp命令时,我得到以下命令

新的你好

Error: Path "/app/app.module.ts" does not exist.
Path "/app/app.module.ts" does not exist.

谁能帮我吗???

解决方法

这是解决方案

Please make sure that your new folder have write permission

如果您使用的是ubuntu,请将以下命令运行到该文件夹

sudo chmod 644 -R foldername

然后运行新的appname

并检查您的节点版本

APP 自动化 01 - 基础操作 API-UIautomatorviewer-APP 定位 - 元素等待 - APP 模拟手势高级操作

APP 自动化 01 - 基础操作 API-UIautomatorviewer-APP 定位 - 元素等待 - APP 模拟手势高级操作

--- 恢复内容开始 ---

 先连接手机:

adb connect 127.0.0.1:7555

APP 基础操作 API

前置代码

# server 启动参数

desired_caps = {}
desired_caps[''platformName''] = ''Android''
desired_caps[''platformVersion''] = ''5.1''
desired_caps[''deviceName''] = ''192.168.56.101:5555''
desired_caps[''appPackage''] = ''com.android.settings''
desired_caps[''appActivity''] = ''.Settings''
 
# 解决输入中文
desired_caps[''unicodeKeyboard''] = True
desired_caps[''resetKeyboard''] = True

# 声明driver对象
driver = webdriver.Remote(''http://127.0.0.1:4723/wd/hub'', desired_caps)
  1. 安装 apk 到手机

    driver.install_app(''app路径'')
  2. 手机中移出 apk

    driver.remove_app(’APP包名‘)
  3. 判断 app 是否已经安装

    driver.is_app_install(’APP包名‘)

     

  4. 发送文件到手机

      import base64
    with open("./push07.txt","r",encoding="utf-8") as f:
        data=str(base64.b64encode(f.read().encode("utf-8")),"utf-8")
        driver.push_file("/sdcard/push07.txt",data)
    参数:
        /sdcard/push07.txt:手机设备上的路径(例如:/sdcard/a.txt)
        data:文件内数据,要求base64编码
        Python3.x中字符都为unicode编码,而b64encode函数的参数为byte类型,需要先转码;
          生成的数据为byte类型,需要将byte转换回去

     

  5. 从手机中拉取文件

    import base64
    data = driver.pull_file(path) # 返回数据为base64编码
    print(str(base64.b64decode(data),''utf-8'')) # base64解码
    参数:
        path: 手机设备上的路径

     

  6. 获取当前屏幕内元素结构

    driver.page_source
    作用:返回当前页面文档,判断特点元素是否存在

 

手机控件查看工具 UIautomatorviewer

作用:用来扫描和分析 Android 应用程序的 UI 控件的工具.

 

APP 元素定位操作

name Value
id id 属性值
Class class 属性值
Xpath xpath 表达式

文字定位:driver.find_element_by_xpath ("//*[@text='' 定位文字 '']")

driver.find_element_by_xpath ("//*[contains (@text,'' 部分文字 '')]")

 

WebDriverWait 显示等待操作

在一个超时时间范围内,每隔一段时间去搜索一次元素是否存在,
如果存在返回定位对象,如果不存在直到超时时间到达,报超时异常错误。
方法:WebDriverWait(driver, timeout, poll_frequency).until(lamda x:x.find_element_by_id(''id属性值''))
  参数:
      1.driver:手机驱动对象
      2.timeout:搜索超时时间
      3.poll_frequency:每次搜索间隔时间,默认时间为0.5s
      4.method:定位方法(匿名函数)

 

APP 元素信息操作 API

  1. 点击元素 .click ()

  2. 发送数据到输入框 .send_keys ()

  3. 清空输入框内容 .clear ()

  4. 获取元素的文本内容 .text

  5. 获取元素的属性值 .get_attribute (value) #value 是元素属性名

  6. 获取元素在屏幕上的坐标 .location

  7. 获取启动名和包名

    获取包名方法:driver.current_package
    获取启动名:driver.current_activity

     

APP 元素事件操作 API

  1. swip 滑动事件

    从一个坐标位置滑动到另一个坐标位置
    # 滑动持续5秒的时间
    driver.swipe(188,659,148,248,5000)

     

  2. scroll 滑动事件

     driver.scroll(开始元素,结束元素)

     

  3. drag 拖拽事件

    driver.drag_and_drop(el1,el2)
  4. 应用置于后台

APP放置后台,模拟热启动
# app置于后台5s后,再次展示当前页面
driver.background_app(5)

 

APP 模拟手势高级操作

TouchAction是AppiumDriver的辅助类,主要针对手势操作,比如滑动、长按、拖动等,
原理是将一系列的动作放在一个链条中发送到服务器,服务器接受到该链条后,解析各个动作,逐个执行。

⚠️所有手势都要通过执行函数才会运行.
  1. 轻敲操作

    方法:tap(element=None, x=None, y=None)
    方法:perform() # 发送命令到服务器执行操作
  2. 按的操作

    方法:press(el=None, x=None, y=None)
    方法:release() # 结束动作,手指离开屏幕
    再 preform()

     

  3. 等待操作

    wait(ms=0)

     

  4. 手指长按操作

    long_press(el=None, x=None, y=None, duration=1000)
    默认为1000毫秒

     

  5. 手指移动操作

     方法:move_to(el=None, x=None, y=None).perform()
    参数:
        1.el:定位的元素
        2.x:相对于前一个元素的X轴偏移量
        3.y:相对于前一个元素的Y轴偏移量

     

     

 

 

--- 恢复内容结束 ---

今天关于数据库 – OS X App.哪种方式是存储数据的最佳方式?数据库中数据存储方式的讲解已经结束,谢谢您的阅读,如果想了解更多关于41 - 数据库-pymysql41 - 数据库-pymysql-DBUtils、ActionController :: RoutingError没有路由与[GET]“ / vendor / assets / stylesheets / bootstrap.min.css”匹配 app / assets / stylesheets / application.css: app / assets / javascript / application.js: app / views / layout / application.html.erb: app / j、angular – ng new hello错误:路径“/app/app.module.ts”不存在.路径“/app/app.module.ts”不存在、APP 自动化 01 - 基础操作 API-UIautomatorviewer-APP 定位 - 元素等待 - APP 模拟手势高级操作的相关知识,请在本站搜索。

本文标签:

上一篇macos – 隐藏NSWindow标题栏背景,如Messages.app(mac怎么隐藏状态栏)

下一篇在NSObject中玩NSSound(带有Objective-C的Mac App)(nsinputstream)