Opérations avancées de l'interface¶
Ce chapitre présente des API d'automatisation plus avancées. Vous pouvez utiliser ces interfaces pour effectuer diverses opérations détaillées. Le contenu de ce chapitre est assez dense, donc si c'est votre première fois, nous vous recommandons de lire attentivement chaque section.
Conseil
Obtenir un élément¶
Vous en avez peut-être déjà eu un aperçu dans les connaissances de base ou les chapitres précédents. Vous devez utiliser un sélecteur pour trouver les éléments pertinents avant de pouvoir interagir avec eux. Vous avez probablement aussi vu où obtenir les paramètres du sélecteur. Les explications suivantes se concentreront sur cet élément. Sur le côté droit de l'image, vous pouvez voir les informations relatives à l'élément "同意" (Accepter).

Attention
Pour l'élément ci-dessus, nous le récupérons généralement via text. La condition pour utiliser text est qu'aucun autre élément sur l'interface actuelle n'ait également le texte "同意". C'est la méthode la plus simple. Vous pouvez également utiliser resourceId, mais notez que resourceId ne représente pas un ID unique, mais un ID de ressource, et une interface peut contenir de nombreux éléments avec le même ID de ressource. D'autres attributs comme packageName, checkable, etc., sont moins courants, mais peuvent être utilisés si text, resourceId, description, etc., ne sont pas disponibles. Nous pouvons obtenir cet élément des manières suivantes.
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 sur un élément¶
Appelez l'interface suivante pour effectuer un clic normal sur un élément. Dans le contexte, cela réalisera l'effet d'un clic manuel sur "Accepter".
element.click()
Si vous devez spécifier la position du clic sur l'élément, vous pouvez spécifier corner. Corner.COR_CENTER représente un clic au centre de l'élément. Vous pouvez également cliquer sur son coin supérieur gauche ou inférieur droit (COR_BOTTOMRIGHT).
element.click_exists(corner=Corner.COR_TOPLEFT)
Effectue un clic long sur l'élément. Lève une exception s'il n'existe pas. Cette interface prend également en charge corner, mais ne permet pas de spécifier la durée du clic long.
element.long_click()
Clique sur l'élément s'il existe. Si l'élément n'existe pas, l'appel à cette interface ne lèvera pas d'exception. Cette interface prend également en charge corner.
element.click_exists()
>>> element.click_exists()
True
Vérifier l'existence¶
Dans de nombreux cas, il est nécessaire de vérifier l'existence d'un élément avant de poursuivre les opérations. Sinon, le flux de travail pourrait rencontrer des exceptions ou effectuer des actions incorrectes sur la mauvaise interface. Vous devrez peut-être utiliser l'interface suivante pour vérifier l'existence dans certaines situations.
element.exists()
Informations sur l'élément¶
Dans certaines situations, vous pourriez vouloir obtenir des informations partielles sur un élément, telles que ses coordonnées, sa zone, ou les chaînes de caractères qu'il contient comme le texte ou la description. Vous pouvez utiliser l'interface suivante pour lire les informations de l'élément.
element.info()
Pour notre élément de test ci-dessus, les informations affichées sont :
>>> 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 { ... }
Astuce
Comme vous pouvez le voir, ces informations sont un peu complexes. C'est le format d'affichage par défaut de protobuf. Vous pouvez accéder directement aux attributs correspondants pour afficher leurs valeurs réelles. Par exemple, pour lire la valeur du text de l'élément, vous pouvez l'utiliser comme suit.
>>> info = element.info()
>>> print (info.text)
同意
Bien sûr, il y a aussi des informations sur les coordonnées de la zone de l'élément, auxquelles vous pouvez également accéder. Par exemple, si vous voulez obtenir les informations sur la zone de l'élément, vous pouvez les afficher comme suit, ou les stocker dans une variable pour des opérations ultérieures.
>>> info = element.info()
>>> print (info.bounds)
La valeur de sortie ou de retour est une information de zone (Bound). Vous découvrirez plus tard que c'est un paramètre également utilisé par une certaine interface de capture d'écran. Oui, vous pouvez passer ce paramètre à l'interface de capture d'écran pour prendre une capture d'écran de cet élément seul, mais nous l'avons déjà encapsulé pour vous.
Vous pourriez également vouloir obtenir la largeur et la hauteur de l'élément pour calculer certains décalages, comme le décalage par rapport à d'autres éléments. Vous pouvez le faire comme ceci.
>>> info = element.info()
>>> print (info.bounds.width, info.bounds.height)
484 138
Ou, obtenir le point central de l'élément, ou les points de coin comme le coin supérieur gauche ou inférieur droit. Bien sûr, les interfaces suivantes retournent généralement des informations de type Point, et vous pouvez obtenir les coordonnées X et Y de l'écran de l'appareil à partir de l'objet Point.
>>> info = element.info()
>>> print (info.bounds.center())
x: 792
y: 1908
>>> print (info.bounds.center().x)
792
L'appel suivant est utilisé pour obtenir les coordonnées des coins de l'élément. L'exemple obtient les coordonnées du coin supérieur gauche. Il prend également en charge l'obtention des coordonnées des quatre coins, tels que bottom-right, top-right, et bottom-left.
>>> info = element.info()
>>> print (info.bounds.corner("top-left"))
x: 550
y: 1839
>>> print (info.bounds.corner("top-left").x)
550
Parcourir les éléments¶
Vous pouvez également parcourir tous les éléments sélectionnés par le sélecteur. Normalement, il se peut qu'il n'y ait qu'un seul élément dans le contexte, donc si vous testez, veuillez choisir un autre sélecteur pour vos tests. Vous pouvez utiliser une boucle for ou d'autres méthodes directement sur le sélecteur pour le parcourir.
for i in element: print (i)
Ou si vous savez qu'il y a plusieurs éléments correspondants et que vous voulez obtenir le N-ième élément, vous pouvez utiliser l'interface suivante.
element_3rd = element.get(3)
Compter les éléments¶
En général, vous n'utiliserez pas directement cette interface. L'appel suivant peut obtenir le nombre d'éléments correspondant à votre sélecteur actuel.
>>> element.count()
1
Capture d'écran d'un élément¶
Nous prenons en charge les captures d'écran au niveau de l'élément, vous permettant de capturer l'image d'un élément individuel sans avoir à faire une capture d'écran complète puis à la recadrer.
element.screenshot(quality=60)
Après avoir pris la capture d'écran, vous pouvez utiliser getvalue pour obtenir les données binaires de la capture, ou la passer directement à une 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...
Ou, si vous n'avez pas besoin de traitement supplémentaire, vous pouvez choisir de sauvegarder directement la capture d'écran dans un fichier local.
>>> element.screenshot(quality=60).save("image.png")
Attendre un élément¶
Dans certaines situations, vous devrez peut-être déterminer si la page actuelle a fini de se charger. En général, vous pouvez le faire en vérifiant si un élément pertinent est déjà affiché. L'exemple suivant attendra que l'élément "同意" apparaisse, avec un temps d'attente maximum de 10 secondes.
Astuce
element.wait_for_exists(10*1000)
>>> element.wait_for_exists(10*1000)
True
Bien sûr, nous ne prenons pas seulement en charge l'attente de l'apparition d'un élément, mais aussi l'attente de sa disparition, c'est-à-dire jusqu'à ce que l'élément disparaisse de l'interface.
element.wait_until_gone(10*1000)
>>> element.wait_until_gone(10*1000)
False
Saisie de texte¶
La saisie de texte est un point qui nécessite une attention particulière. Nous ne pouvons pas saisir de texte dans un bouton "Accepter" car c'est un bouton. Prenons maintenant un élément de champ de saisie comme exemple. Les informations de base de cet élément sont présentées ci-dessous.

Attention
Astuce
Pour le champ de saisie ci-dessus, nous pouvons appeler l'interface suivante pour y saisir la chaîne "你好世界" (Bonjour le monde). Bien sûr, la saisie de chaînes en anglais ou d'autres chaînes Unicode est également prise en charge. Il vous suffit de l'utiliser comme suit pour saisir du texte dans le champ.
>>> element = d(text="搜索感兴趣的内容")
>>> element.set_text("你好世界")
True
Ou, si vous avez soudainement envie d'obtenir le texte actuellement affiché dans ce champ de saisie, vous pouvez l'appeler comme ceci.
Attention
>>> element = d(className="android.widget.EditText")
>>> element.get_text()
'你好世界'
Ou encore, pour effacer le contenu actuellement saisi. Normalement, la saisie de texte efface automatiquement le texte précédent, mais vous pouvez également l'effacer manuellement.
Astuce
>>> element = d(className="android.widget.EditText")
>>> element.clear_text_field( )
True
Remarque
Défilement normal¶
Utilisez l'interface suivante pour effectuer des opérations de défilement sur l'interface, comme faire défiler une liste vers le haut ou le bas pour changer de page. L'appel suivant réalise un défilement vers le haut. Ajustez step vous-même ; plus la valeur est grande, plus la vitesse de défilement sera lente, ce qui convient aux défilements nécessitant une plus grande précision.
Attention
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
Défilement rapide¶
Le défilement rapide (fling) simule le comportement d'un utilisateur balayant rapidement l'écran. Cette opération fait défiler l'écran rapidement et convient à la simulation d'actions de navigation rapide. L'exemple suivant fait défiler l'écran de haut en bas. Dans l'exemple, le sélecteur est vide, mais vous devrez peut-être le spécifier en fonction de la situation.
d().fling_from_top_to_bottom()
Défilement rapide de bas en haut
d().fling_from_bottom_to_top()
Défilement rapide de gauche à droite
d().fling_from_left_to_right()
Défilement rapide de droite à gauche
d().fling_from_right_to_left()
Attention
>>> element = d(resourceId="com.tencent.news:id/important_list_content")
>>> element.fling_from_bottom_to_top()
True
Mise à jour en cours...
Autres opérations¶
# Faire glisser cette application dans le dossier "Shopping" (à modifier selon la situation réelle)
element.drag_to(Selector(text="购物"))
#########
# Trouver des éléments frères ou enfants
#########
# Parfois, il y a des éléments en double ou sans caractéristiques distinctives, ce qui les rend difficiles à localiser
# Dans ce cas, vous pouvez réduire la portée de la recherche en trouvant des éléments enfants/frères
# Élément enfant, par exemple : dans une boîte de dialogue de connexion de chat, les champs de saisie sont des éléments enfants de la boîte de dialogue
# Élément frère, par exemple : dans une boîte de dialogue de connexion, les champs nom d'utilisateur et mot de passe sont des éléments frères (normalement)
form = d(resourceId="login_form")
form.child(index=1)
# Ceci obtiendra l'élément à l'index 0 sous login_form
form.child(index=1).sibling()
# Vous pouvez également trouver le bouton "Mot de passe oublié" qui est un frère de login_form de cette manière
# (En réalité, cela peut déjà être fait en se basant sur la chaîne de caractères, donc ce n'est pas nécessaire, c'est juste pour la démonstration)
form.sibling(textContains="找回密码")
# Ce sont eux-mêmes des éléments, vous pouvez effectuer n'importe quelle opération d'élément sur eux
# Autres, faire défiler continuellement vers le bas/gauche/droite/haut jusqu'à la fin
# Comme il n'est pas toujours possible de faire défiler jusqu'à la fin ou de détecter la fin du défilement
# le paramètre max_swipes est obligatoire
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 défilement plus mécanique
#########
step = 60
max_swipes = 32
# Faire défiler de haut en bas de 'step' pas
d().scroll_from_top_to_bottom(step)
# Faire défiler de bas en haut de 'step' pas
d().scroll_from_bottom_to_top(step)
# Faire défiler de gauche à droite de 'step' pas
d().scroll_from_left_to_right(step)
# Faire défiler de droite à gauche de 'step' pas
d().scroll_from_right_to_left(step)
# Autres, faire défiler continuellement vers le bas/gauche/droite/haut jusqu'à la fin
# Identique à la description de fling ci-dessus
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)