Fortgeschrittene Bedienung der Benutzeroberfläche¶
Dieses Kapitel stellt Ihnen tiefergehende Automatisierungsschnittstellen vor, mit denen Sie verschiedene detaillierte Operationen durchführen können. Der Inhalt dieses Kapitels ist umfangreich. Wenn Sie zum ersten Mal damit in Berührung kommen, empfehlen wir Ihnen, jeden Abschnitt geduldig durchzulesen.
Tipp
Elemente abrufen¶
Sie haben möglicherweise bereits in den Grundlagen oder in den vorherigen Abschnitten einige Kenntnisse darüber erlangt. Sie müssen die relevanten Elemente über Selektoren finden, um Operationen durchführen zu können. Sie haben wahrscheinlich auch gesehen, wo Sie die Selektorparameter erhalten können. Die folgenden Erläuterungen werden sich um dieses Element drehen. Auf der rechten Seite dieses Bildes sehen Sie die relevanten Informationen zum Element „同意“ (Zustimmen).

Achtung
Für das obige Element verwenden wir im Allgemeinen text, um es abzurufen. Die Bedingung für die Verwendung von text ist, dass auf der aktuellen Oberfläche kein anderes Element ebenfalls den Text „同意“ (Zustimmen) hat. Dies ist die einfachste Methode. Alternativ können Sie auch resourceId verwenden. Beachten Sie jedoch, dass resourceId hier nicht für eine eindeutige ID steht, sondern für eine Ressourcen-ID, und eine Benutzeroberfläche kann viele Elemente mit derselben Ressourcen-ID enthalten. Andere Felder wie packageName, checkable usw. werden seltener verwendet, können aber versucht werden, wenn text, resourceId, description usw. nicht verfügbar sind. Wir können dieses Element auf folgende Weisen abrufen.
element = d(text="同意")
element = d(text="同意", resourceId="com.tencent.news:id/btm_first_agree")
element = d(resourceId="com.tencent.news:id/btm_first_agree")
Klick auf Elemente¶
Rufen Sie die folgende Schnittstelle auf, um einen normalen Klick auf ein Element auszuführen. Im Kontext wird für Sie der Effekt eines manuellen Klicks auf „Zustimmen“ realisiert.
element.click()
Wenn Sie die Position des Klicks auf dem Element angeben müssen, können Sie corner angeben. Corner.COR_CENTER bedeutet, auf den Mittelpunkt des Elements zu klicken. Sie können auch auf die obere linke oder untere rechte Ecke (COR_BOTTOMRIGHT) klicken.
element.click_exists(corner=Corner.COR_TOPLEFT)
Führt einen langen Klick auf dem Element aus; löst eine Ausnahme aus, wenn es nicht existiert. Diese Schnittstelle unterstützt auch corner, die Dauer des langen Klicks kann nicht angegeben werden.
element.long_click()
Klickt, wenn das Element existiert. Wenn das Element nicht existiert, löst der Aufruf dieser Schnittstelle keine Ausnahme aus. Diese Schnittstelle unterstützt ebenfalls corner.
element.click_exists()
>>> element.click_exists()
True
Existenzprüfung¶
In vielen Fällen ist es notwendig, die Existenz eines Elements zu überprüfen, bevor weitere Operationen durchgeführt werden, andernfalls kann der nachfolgende Prozess auf einen Fehler stoßen oder falsche Aktionen auf der falschen Oberfläche ausführen. Möglicherweise müssen Sie in bestimmten Situationen die folgende Schnittstelle zur Existenzprüfung verwenden.
element.exists()
Elementinformationen¶
In einigen Fällen möchten Sie möglicherweise Teile der Informationen eines Elements abrufen, zum Beispiel die Koordinaten, den Bereich oder die im Element enthaltenen Text- oder Beschreibungsinformationen. Sie können die folgende Schnittstelle verwenden, um Elementinformationen zu lesen.
element.info()
Für unser obiges Testelement lautet die Ausgabeinformation wie folgt:
>>> 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 { ... }
Hinweis
Wie Sie sehen, sind diese Informationen relativ komplex. Dies ist das Standard-Druckformat von protobuf. Sie können den tatsächlichen Wert direkt ausgeben, indem Sie auf das entsprechende Attribut zugreifen. Wenn Sie beispielsweise den Wert des text-Attributs eines Elements lesen möchten, können Sie dies wie folgt tun.
>>> info = element.info()
>>> print (info.text)
同意
Natürlich gibt es auch Informationen zu den Bereichskoordinaten des Elements, auf die Sie ebenfalls zugreifen können. Wenn Sie beispielsweise die Bereichsinformationen des Elements abrufen möchten, können Sie dies wie folgt tun, um die Bereichsinformationen auszugeben, oder sie für nachfolgende Operationen in einer Variablen speichern.
>>> info = element.info()
>>> print (info.bounds)
Der ausgegebene oder zurückgegebene Wert ist eine Bereichsinformation (Bound). Sie werden später feststellen, dass dies ein Parameter ist, der auch von einer Screenshot-Schnittstelle verwendet wird. Ja, Sie können diesen Parameter an die Screenshot-Schnittstelle übergeben, um einen Screenshot nur von diesem Element zu erstellen, aber wir haben dies bereits für Sie gekapselt.
Vielleicht möchten Sie auch die Breite und Höhe des Elements abrufen, um bestimmte Offsets zu berechnen, zum Beispiel den Offset relativ zu anderen Elementen. Das können Sie so tun:
>>> info = element.info()
>>> print (info.bounds.width, info.bounds.height)
484 138
Oder rufen Sie den Mittelpunkt oder die Eckpunkte des Elements ab, wie z.B. oben links oder unten rechts. Die folgenden Schnittstellen geben normalerweise Point-Informationen zurück. Sie können auch die entsprechenden X- und Y-Koordinaten des Gerätebildschirms aus dem Point-Objekt abrufen.
>>> info = element.info()
>>> print (info.bounds.center())
x: 792
y: 1908
>>> print (info.bounds.center().x)
792
Der folgende Aufruf wird verwendet, um die Eckpunktkoordinaten des Elements abzurufen. Das Beispiel ruft die Koordinaten der oberen linken Ecke des Elements ab. Darüber hinaus wird das Abrufen der Koordinaten aller vier Eckpunkte wie bottom-right, top-right und bottom-left unterstützt.
>>> info = element.info()
>>> print (info.bounds.corner("top-left"))
x: 550
y: 1839
>>> print (info.bounds.corner("top-left").x)
550
Iteration über Elemente¶
Sie können auch über alle vom Selektor ausgewählten Elemente iterieren. Normalerweise gibt es im Kontext möglicherweise nur ein solches Element, daher wählen Sie bitte einen anderen Selektor zum Testen. Sie können einfach eine for-Schleife oder eine andere Methode direkt auf dem Selektor verwenden, um zu iterieren.
for i in element: print (i)
Oder wenn Sie wissen, dass es mehrere übereinstimmende Elemente gibt und Sie das n-te übereinstimmende Element erhalten möchten, können Sie die folgende Schnittstelle verwenden.
element_3rd = element.get(3)
Elementanzahl¶
Normalerweise werden Sie diese Schnittstelle nicht direkt verwenden. Der folgende Aufruf kann die Anzahl der Elemente abrufen, die mit Ihrem aktuellen Selektor übereinstimmen.
>>> element.count()
1
Screenshot von Elementen¶
Wir unterstützen Screenshots auf Elementebene, sodass Sie das Bild eines Elements einzeln erfassen können, ohne einen Screenshot des gesamten Bildschirms machen und ihn dann zuschneiden zu müssen.
element.screenshot(quality=60)
Nachdem Sie den Screenshot erstellt haben, können Sie getvalue verwenden, um die binären Daten des Screenshots direkt abzurufen, oder ihn direkt an ein PIL.Image-Objekt übergeben.
>>> 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...
Oder wenn Sie keine weitere Verarbeitung benötigen, können Sie den Screenshot auch direkt in einer lokalen Datei speichern.
>>> element.screenshot(quality=60).save("image.png")
Warten auf Elemente¶
In einigen Situationen müssen Sie möglicherweise feststellen, ob die aktuelle Seite vollständig geladen ist. Normalerweise können Sie dies tun, indem Sie prüfen, ob ein relevantes Element bereits angezeigt wird, um festzustellen, ob die aktuelle Seite geladen ist. Das folgende Beispiel wartet auf das Erscheinen des Elements „同意“ (Zustimmen), mit einer maximalen Wartezeit von 10 Sekunden.
Hinweis
element.wait_for_exists(10*1000)
>>> element.wait_for_exists(10*1000)
True
Natürlich unterstützen wir nicht nur das Warten auf das Erscheinen eines Elements, sondern auch das Warten auf sein Verschwinden, das heißt, bis das Element von der Benutzeroberfläche verschwindet.
element.wait_until_gone(10*1000)
>>> element.wait_until_gone(10*1000)
False
Texteingabe¶
Die Texteingabe ist ein Bereich, der besondere Aufmerksamkeit erfordert. Wir können keinen Text in eine „Zustimmen“-Schaltfläche eingeben, da es sich um eine Schaltfläche handelt. Jetzt nehmen wir ein Eingabefeld-Element als Beispiel, dessen grundlegende Informationen unten gezeigt werden.

Achtung
Hinweis
Für das obige Eingabefeld können wir die folgende Schnittstelle aufrufen, um die Zeichenfolge „你好世界“ (Hallo Welt) einzugeben. Natürlich wird auch die Eingabe von englischen oder anderen Unicode-Zeichenfolgen unterstützt. Sie müssen es nur wie unten gezeigt verwenden, um Text in das Feld einzugeben.
>>> element = d(text="搜索感兴趣的内容")
>>> element.set_text("你好世界")
True
Oder wenn Sie plötzlich die Idee haben, den aktuell im Eingabefeld angezeigten Text abzurufen, können Sie dies wie folgt tun.
Achtung
>>> element = d(className="android.widget.EditText")
>>> element.get_text()
'你好世界'
Oder um den aktuell eingegebenen Inhalt zu löschen. Normalerweise wird beim Eingeben von Text der vorherige Text automatisch gelöscht, aber Sie können ihn auch manuell löschen.
Hinweis
>>> element = d(className="android.widget.EditText")
>>> element.clear_text_field( )
True
Notiz
Normales Wischen (Swipe)¶
Verwenden Sie die folgende Schnittstelle, um Wischoperationen auf der Benutzeroberfläche durchzuführen, zum Beispiel das Scrollen nach oben und unten in einer Liste. Der folgende Aufruf implementiert ein Wischen nach oben. Passen Sie step selbst an; je größer der Wert, desto langsamer die Wischgeschwindigkeit, was für Wischvorgänge mit hoher Präzision geeignet ist.
Achtung
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
Schnelles Wischen (Fling)¶
Schnelles Wischen (Fling) ähnelt dem Verhalten einer Person, die schnell über den Bildschirm wischt. Diese Operation wischt schnell über den Bildschirm und eignet sich zur Simulation von Aktionen wie schnellem Durchsuchen. Das folgende Beispiel wischt von oben nach unten über den Bildschirm. Im Beispiel ist der Selektor leer, Sie müssen jedoch je nach Situation entscheiden, ob Sie einen Selektor angeben.
d().fling_from_top_to_bottom()
Schnelles Wischen von unten nach oben
d().fling_from_bottom_to_top()
Schnelles Wischen von links nach rechts
d().fling_from_left_to_right()
Schnelles Wischen von rechts nach links
d().fling_from_right_to_left()
Achtung
>>> element = d(resourceId="com.tencent.news:id/important_list_content")
>>> element.fling_from_bottom_to_top()
True
Wird aktualisiert...
Weitere Operationen¶
# Diese APP in den Ordner „Einkaufen“ ziehen (je nach tatsächlicher Situation anpassen)
element.drag_to(Selector(text="购物"))
#########
# Gleichgeordnete oder untergeordnete Elemente finden
#########
# Manchmal gibt es doppelte Elemente oder Elemente ohne klare Merkmale, die schwer zu lokalisieren sind
# In diesem Fall können Sie den Suchbereich eingrenzen, indem Sie nach untergeordneten/gleichgeordneten Elementen suchen
# Untergeordnete Elemente, Beispiel: In einem Chat-Anmeldeformular sind die Eingabefelder untergeordnete Elemente des Anmeldeformulars
# Gleichgeordnete Elemente, Beispiel: Das Benutzername- und das Passwortfeld in einem Chat-Eingabefeld sind (normalerweise) gleichgeordnete Elemente
form = d(resourceId="login_form")
form.child(index=1)
# Dies ruft das Element mit dem Index 1 unter login_form ab
form.child(index=1).sibling()
# Sie können auch so nach der Schaltfläche „Passwort vergessen“ suchen, die auf derselben Ebene wie login_form liegt
# (Eigentlich kann dies bereits durch eine Zeichenfolgenprüfung erfolgen, dies ist also nicht notwendig, hier nur zur Demonstration)
form.sibling(textContains="找回密码")
# Sie sind selbst ein Element, Sie können jede Element-Operation darauf anwenden
# Sonstiges, kontinuierlich nach unten/links/rechts/oben wischen, bis das Ende erreicht ist
# Da es nicht immer möglich ist, bis zum Ende zu wischen oder das Erreichen des Endes zu erkennen
# ist der Parameter max_swipes erforderlich
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: Eher mechanisches Wischen
#########
step = 60
max_swipes = 32
# Wischt step Schritte von oben nach unten
d().scroll_from_top_to_bottom(step)
# Wischt step Schritte von unten nach oben
d().scroll_from_bottom_to_top(step)
# Wischt step Schritte von links nach rechts
d().scroll_from_left_to_right(step)
# Wischt step Schritte von rechts nach links
d().scroll_from_right_to_left(step)
# Sonstiges, kontinuierlich nach unten/links/rechts/oben wischen, bis das Ende erreicht ist
# Wie oben bei fling beschrieben
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)