Operaciones Avanzadas de la Interfaz¶
Este capítulo le presenta APIs de automatización más profundas, a través de las cuales puede realizar diversas operaciones detalladas. El contenido de este capítulo es extenso; si es la primera vez que lo aborda, le recomendamos que lea cada sección con paciencia.
Consejo
Obtener Elemento¶
Es posible que ya tenga algún conocimiento sobre esto a partir de los conceptos básicos o de secciones anteriores. Necesita encontrar los elementos relevantes a través de un selector para poder operarlos. Probablemente también haya visto dónde obtener los parámetros del selector. Las siguientes introducciones girarán en torno a este elemento. En el lado derecho de esta imagen, puede ver la información relevante del elemento "同意" (Aceptar).

Atención
Para el elemento anterior, generalmente lo obtenemos a través de text. La condición para usar text es que no haya otro elemento en la interfaz actual cuyo text también sea "同意". Este es el método más simple. En segundo lugar, también puede usar resourceId, pero debe tener en cuenta que el resourceId aquí no representa un ID único, sino un ID de recurso, y una interfaz puede contener muchos elementos con el mismo ID de recurso. Otros como packageName, checkable, etc., no se usan comúnmente, pero si text, resourceId, description, etc., no están disponibles, puede intentar usar estos campos. Podemos obtener este elemento de las siguientes maneras.
element = d(text="同意")
element = d(text="同意", resourceId="com.tencent.news:id/btm_first_agree")
element = d(resourceId="com.tencent.news:id/btm_first_agree")
Clic en Elemento¶
Llame a la siguiente API para realizar una operación de clic normal en un elemento. En el contexto, esto logrará el efecto de hacer clic manualmente en "Aceptar".
element.click()
Si necesita especificar la posición del clic en el elemento, puede especificar corner. Corner.COR_CENTER representa hacer clic en el punto central del elemento. También puede hacer clic en su esquina superior izquierda o inferior derecha (COR_BOTTOMRIGHT).
element.click_exists(corner=Corner.COR_TOPLEFT)
Realiza una operación de clic largo en este elemento. Si no existe, se lanza una excepción. Esta API también admite corner, pero no se puede especificar la duración del clic largo.
element.long_click()
Hace clic si el elemento existe. Si el elemento no existe, llamar a esta API no provocará una excepción. Esta API también admite corner.
element.click_exists()
>>> element.click_exists()
True
Verificar Existencia¶
En muchas situaciones, antes de realizar operaciones adicionales, es necesario verificar la existencia de un elemento. De lo contrario, los procesos posteriores podrían encontrar excepciones o realizar operaciones incorrectas en la interfaz equivocada. Es posible que necesite usar la siguiente API para verificar la existencia en ciertas situaciones.
element.exists()
Información del Elemento¶
En algunos casos, es posible que desee obtener parte de la información de un elemento, como sus coordenadas, área, o cadenas de texto como el texto o la descripción que contiene. Puede leer la información del elemento a través de la siguiente API.
element.info()
En nuestro elemento de prueba anterior, la información de salida para este elemento de prueba es:
>>> info = element.info()
>>> print (info)
bounds { ... }
className: "android.widget.TextView"
clickable: true
enabled: true
focusable: true
packageName: "com.tencent.news"
resourceName: "com.tencent.news:id/btn_first_agree"
text: "\345\220\214\346\204\217"
visibleBounds { ... }
Sugerencia
Como puede ver, esta información es relativamente compleja. Este es el formato de impresión predeterminado de protobuf. Puede acceder directamente a las propiedades correspondientes para imprimir su valor real. Por ejemplo, si desea leer el valor del text del elemento, puede usarlo como se muestra a continuación.
>>> info = element.info()
>>> print (info.text)
同意
Por supuesto, también hay información relacionada con las coordenadas del área del elemento, a la que también puede acceder. Por ejemplo, si ahora desea obtener la información del área correspondiente a este elemento, puede usarlo como se muestra a continuación para imprimir la información del área. También puede obtenerla como una variable para operaciones posteriores.
>>> info = element.info()
>>> print (info.bounds)
El valor de salida o devuelto es una información de área (Bound). Más adelante descubrirá que este es un parámetro que también utiliza una API de captura de pantalla. Sí, puede pasar este parámetro a la API de captura de pantalla para tomar una captura de pantalla solo de este elemento, pero ya lo hemos encapsulado para usted.
También es posible que desee obtener el ancho y el alto del elemento para calcular ciertos desplazamientos, como el desplazamiento de otros elementos relativos. Puede hacerlo así:
>>> info = element.info()
>>> print (info.bounds.width, info.bounds.height)
484 138
O bien, obtener el punto central del elemento, o puntos de esquina como la esquina superior izquierda o inferior derecha. Por supuesto, las siguientes APIs suelen devolver información de Point, y también puede obtener las coordenadas de pantalla del dispositivo en los ejes X e Y correspondientes del objeto Point.
>>> info = element.info()
>>> print (info.bounds.center())
x: 792
y: 1908
>>> print (info.bounds.center().x)
792
La siguiente llamada se utiliza para obtener las coordenadas de las esquinas del elemento. El ejemplo obtiene las coordenadas de la esquina superior izquierda del elemento. Además, admite la obtención de las coordenadas de las cuatro esquinas, como bottom-right, top-right, bottom-left, etc.
>>> info = element.info()
>>> print (info.bounds.corner("top-left"))
x: 550
y: 1839
>>> print (info.bounds.corner("top-left").x)
550
Recorrer Elementos¶
También puede recorrer todos los elementos seleccionados por el selector. Normalmente, este elemento puede ser único en el contexto, por lo que si está probando, elija otros selectores para la prueba. Simplemente use un bucle for u otro método en el selector para recorrerlos.
for i in element: print (i)
O si sabe que existen múltiples elementos coincidentes y desea obtener el N-ésimo elemento coincidente específico, puede usar la siguiente API para obtenerlo.
element_3rd = element.get(3)
Contar Elementos¶
Normalmente no usará esta API directamente. La siguiente llamada puede obtener el número de elementos que coinciden con su selector actual.
>>> element.count()
1
Captura de Pantalla de Elemento¶
Admitimos la captura de pantalla a nivel de elemento, lo que le permite capturar la imagen de un elemento individualmente sin necesidad de una captura de pantalla completa y posterior recorte.
element.screenshot(quality=60)
Después de tomar la captura de pantalla, puede usar directamente getvalue para obtener los datos binarios de la captura, o pasarla directamente a una PIL Image.
>>> element.screenshot(quality=60).getvalue()
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xe2\x02(ICC_PROFILE\x00\x01\x01\x00\x00\x02\x18\x00\x00\x00\x00\x02\x10\x00\x00mntrRGB XYZ \x00\x00...
O si no necesita procesarla más, también puede optar por guardar la captura de pantalla directamente en un archivo local.
>>> element.screenshot(quality=60).save("image.png")
Esperar por Elemento¶
En algunos casos, es posible que necesite determinar si la página actual ha terminado de cargarse. Generalmente, puede determinar si la página actual ha terminado de cargarse verificando si un elemento relevante ya se muestra. El siguiente ejemplo esperará a que aparezca el elemento "同意", con un tiempo de espera máximo de 10 segundos.
Sugerencia
element.wait_for_exists(10*1000)
>>> element.wait_for_exists(10*1000)
True
Por supuesto, no solo admitimos la espera a que aparezca un elemento, sino también la espera a que un elemento desaparezca, es decir, hasta que el elemento desaparezca de la interfaz.
element.wait_until_gone(10*1000)
>>> element.wait_until_gone(10*1000)
False
Entrada de Texto¶
La entrada de texto es un área que requiere una atención relativamente especial. No podemos introducir texto en un botón de "Aceptar" porque es un botón. Ahora, tomemos un elemento de campo de entrada para la introducción. La información básica de este elemento es la siguiente.

Atención
Sugerencia
Para el campo de entrada anterior, podemos llamar a la siguiente API para introducir la cadena "你好世界" (Hola Mundo) en el campo de entrada. Por supuesto, también admite la entrada de cadenas en inglés u otras cadenas unicode. Solo necesita usarlo como se muestra a continuación para introducir texto en el cuadro.
>>> element = d(text="搜索感兴趣的内容")
>>> element.set_text("你好世界")
True
O, si de repente se le ocurre que desea obtener el texto que se muestra actualmente en este campo de entrada, puede llamarlo de esta manera.
Atención
>>> element = d(className="android.widget.EditText")
>>> element.get_text()
'你好世界'
O para borrar el contenido introducido actualmente. Normalmente, introducir texto borra automáticamente el texto anterior, pero también puede borrarlo manualmente.
Sugerencia
>>> element = d(className="android.widget.EditText")
>>> element.clear_text_field( )
True
Nota
Deslizamiento Normal¶
Use la siguiente API para realizar operaciones de deslizamiento en la interfaz, como pasar de página hacia arriba y hacia abajo en una lista. La siguiente llamada implementa un deslizamiento hacia arriba. Ajuste step según sea necesario; cuanto mayor sea, más lenta será la velocidad de deslizamiento, lo que es más adecuado para deslizamientos que requieren alta precisión.
Atención
d().swipe(direction=Direction.DIR_UP, step=32)
>>> element = d(resourceId="com.tencent.news:id/important_list_content")
>>> element.swipe(direction=Direction.DIR_UP, step=32)
True
| Indicador de Dirección | Descripción |
|---|---|
| Direction.DIR_UP | Deslizar hacia arriba |
| Direction.DIR_LEFT | Deslizar hacia la izquierda |
| Direction.DIR_DOWN | Deslizar hacia abajo |
| Direction.DIR_RIGHT | Deslizar hacia la derecha |
Deslizamiento Rápido (Fling)¶
El deslizamiento rápido es similar al comportamiento humano de deslizar rápidamente la pantalla. Esta operación deslizará la pantalla rápidamente, adecuada para simular operaciones como la navegación rápida. El siguiente ejemplo desliza la pantalla de arriba hacia abajo. En el ejemplo, el selector está vacío; aún necesita decidir si completar el selector según la situación real.
d().fling_from_top_to_bottom()
Deslizamiento rápido de abajo hacia arriba
d().fling_from_bottom_to_top()
Deslizamiento rápido de izquierda a derecha
d().fling_from_left_to_right()
Deslizamiento rápido de derecha a izquierda
d().fling_from_right_to_left()
Atención
>>> element = d(resourceId="com.tencent.news:id/important_list_content")
>>> element.fling_from_bottom_to_top()
True
Actualizando...
Otras Operaciones¶
# Arrastra esta APP a la carpeta "Compras" (modificar según la situación real)
element.drag_to(Selector(text="购物"))
#########
# Encontrar elementos hermanos o hijos
#########
# A veces hay elementos duplicados o sin características distintivas, lo que dificulta su localización
# En estos casos, puedes reducir el rango de búsqueda encontrando elementos hijos/hermanos
# Elemento hijo, por ejemplo: en un cuadro de diálogo de inicio de sesión de chat, los campos de entrada son elementos hijos del cuadro de diálogo.
# Elemento hermano, por ejemplo: los campos de nombre de usuario y contraseña dentro de un formulario de inicio de sesión son elementos hermanos (normalmente).
form = d(resourceId="login_form")
form.child(index=1)
# Esto obtendrá el elemento con índice 1 dentro de login_form
form.child(index=1).sibling()
# También puedes encontrar el botón "Recuperar contraseña", que es hermano de login_form, de esta manera
# (En realidad, ya se puede identificar por el texto, por lo que no es necesario hacerlo así, esto es solo una demostración)
form.sibling(textContains="找回密码")
# Son elementos en sí mismos, puedes realizar cualquier operación de elemento sobre ellos
# Otros, deslizar continuamente hacia abajo/izquierda/derecha/arriba hasta llegar al final
# Como no siempre es posible deslizar hasta el final o detectar que se ha llegado al final
# el parámetro max_swipes es obligatorio
d().fling_from_top_to_bottom_to_end(max_swipes=32)
d().fling_from_bottom_to_top_to_end(max_swipes=32)
d().fling_from_left_to_right_to_end(max_swipes=32)
d().fling_from_right_to_left_to_end(max_swipes=32)
#########
# scroll: un deslizamiento más mecánico
#########
step = 60
max_swipes = 32
# Deslizar hacia abajo step pasos
d().scroll_from_top_to_bottom(step)
# Deslizar hacia arriba step pasos
d().scroll_from_bottom_to_top(step)
# Deslizar hacia la derecha step pasos
d().scroll_from_left_to_right(step)
# Deslizar hacia la izquierda step pasos
d().scroll_from_right_to_left(step)
# Otros, deslizar continuamente hacia abajo/izquierda/derecha/arriba hasta llegar al final
# Igual que en la descripción de fling anterior
d().scroll_from_top_to_bottom_to_end(max_swipes, step)
d().scroll_from_bottom_to_top_to_end(max_swipes, step)
d().scroll_from_left_to_right_to_end(max_swipes, step)
d().scroll_from_right_to_left_to_end(max_swipes, step)