Google Chrome Remote Control / Browser Automation

      Google Chrome Remote Control / Browser Automation

      Mit dem diesem Programm kann man den google chrome Browser fernsteuern und z.B. das ausfüllen von Formularen oder Spiele automatisieren.
      Das ganze eignet sich auch um Bots für Browsergames zu entwickeln.
      Im integrierten Skripteditor kann man ein C# Programm schreiben und dieses direkt ausführen lassen.
      Dazu gibt es verschiedene Werkzeuge welche einem das entwickeln erleichtern wie z.B. ein integriertes Log und kontextbezoge Vervollständigungsvorschläge im Skripteditor.

      Zur Interaktion mit der Webseite stehen alle üblichen Funktionen und mehr zur Verfügung wie z.B.:
      • auswählen von Elementen per XPath oder Id
      • auslesen/verändern des HTML von ausgewählten Elementen oder der ganzen Seite.
      • lesen und schreiben von Attributen.
      • Elemente klicken.
      • komfortables parsen von HTML mit HtmlAgilityPack um umfangreiche Auswertungen vorzunehmen und effizient interessante Infos zu extrahieren.

      Da das Programm zu groß ist um es hier anzuhängen verlinke ich hier die offizielle Bezugsquelle: github.com/Arcitectus/Limbara/releases
      Dateien

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „0ptimist“ ()

      Beispielskripte

      Hier zeige ich Beispielskripte.

      Den Anfang macht ein Bot für das Spiel Wurzelimperium:
      da das mit der Formatierung noch nicht so hinhaut hänge ich dieses Skript auch nochmal als Datei an.
      Spoiler anzeigen

      C# - CSharp

      1. // Wurzelimperium Bot
      2. // Funktionen: ernten, pflanzen, gießen.
      3. using HtmlAgilityPack;
      4. var RundePauseMin = 100;
      5. var RundePauseMax = 400;
      6. static int PlantReadyToHarvestLevel = 4;
      7. static string[] PflanzeImgName = new[]
      8. {
      9. "karotte",
      10. "salat",
      11. "radieschen",
      12. "gurke",
      13. // hier die namen der pflanzen aus den bilddateinamen eintragen die der bot berücksichtigen soll.
      14. // <div class="plantImage dim1x1" style="background: url(http://pics.wurzelimperium.de/pics/produkte/karotte_04.gif);"></div>
      15. };
      16. static bool HasPlantFromFileName(string FileName) =>
      17. PflanzeImgName.Any(fn => FileName?.RegexMatchSuccessIgnoreCase(fn) ?? false);
      18. Host.Log("versuche zu browser zu verbinden....");
      19. var Process = Limbara.App.ReuseOrCreateProcess()?.Result;
      20. var ConnectionAttempt = Process?.ReuseOrOpenConnection();
      21. var Connection = ConnectionAttempt?.Result;
      22. if(null == Connection)
      23. {
      24. throw new Exception("Verbindung zu Browser fehlgeschlagen, " + ConnectionAttempt?.Error?.Message);
      25. }
      26. Host.Log("Browser wurde geöffnet. Melde dich im Spiel an und wechsele in die Gartenansicht. Dann setze das Skript mit dem 'play' Knopf fort.");
      27. Host.Delay(1111);
      28. Connection.Document.Result.locationHref = "http://s14.wurzelimperium.de/main.php?page=garden";
      29. Host.Break();
      30. // <div class="menu-button" onclick="selectMode(0,true,selected)" id="anpflanzen"></div>
      31. IHTMLElement ButtonPflanzen(IDocument Doc) => Doc.GetElementFromXPath("//*[@id='anpflanzen']");
      32. // <div class="menu-button" onclick="selectMode(1,true,selected)" id="ernten"></div>
      33. IHTMLElement ButtonErnten(IDocument Doc) => Doc.GetElementFromXPath("//*[@id='ernten']");
      34. // <div class="menu-button" onclick="selectMode(2,true,selected)" id="giessen"></div>
      35. IHTMLElement ButtonGiessen(IDocument Doc) => Doc.GetElementFromXPath("//*[@id='giessen']");
      36. class Tile
      37. {
      38. public HtmlNode tileNode;
      39. public HtmlNode plantImageNode;
      40. // public string outerHTML;
      41. public string plantImageStyle;
      42. public string plantImageFileName;
      43. public int? plantLevel;
      44. public bool hasPlant;
      45. public bool readyToHarvest;
      46. public HtmlNode irrigationNode;
      47. public string irrigationFileName;
      48. public bool irrigationActive;
      49. public bool readyToWater;
      50. public bool readyToPlant;
      51. // <div class="plantImage dim1x1" style="background: url(http://pics.wurzelimperium.de/pics/produkte/karotte_04.gif);"></div>
      52. const string PlantImageFileNameRegexPattern = @"background\:\s*url\([^)]*/([^)]*)\)";
      53. public Tile(HtmlNode tileNode)
      54. {
      55. this.tileNode = tileNode;
      56. if(null == tileNode)
      57. return;
      58. plantImageNode = tileNode.SelectSingleNode("./div[contains(@class, 'plantImage')]");
      59. plantImageStyle = plantImageNode.GetAttributeValue("style", "");
      60. plantImageFileName = plantImageStyle.ValueFromRegexMatchGroupAtIndex(PlantImageFileNameRegexPattern, 1);
      61. var plantLevelString = plantImageFileName?.ValueFromRegexMatchGroupAtIndex(@"(\d+)", 1);
      62. // remove leading zeros before parsing.
      63. plantLevel = plantLevelString?.TrimStart('0')?.TryParseInt();
      64. hasPlant = HasPlantFromFileName(plantImageFileName);
      65. readyToHarvest = hasPlant && PlantReadyToHarvestLevel <= plantLevel;
      66. irrigationNode = tileNode.SelectSingleNode("./img[contains(@id, '_water')]");
      67. irrigationFileName = irrigationNode?.GetAttributeValue("src", "");
      68. irrigationActive = irrigationFileName?.Contains("gegossen") ?? true;
      69. readyToWater = hasPlant && !irrigationActive && !readyToHarvest;
      70. readyToPlant = plantImageFileName == "0.gif";
      71. }
      72. }
      73. class Garden
      74. {
      75. HtmlNode html;
      76. public Tile[] setTile;
      77. public Garden(HtmlNode html)
      78. {
      79. this.html = html;
      80. // <div class="gardenfield row7 col5 feld" id="gardenTile107" style="z-index:705">
      81. setTile = html?.SelectNodes("//div[contains(@id, 'gardenTile')]")?.Select(tileNode => new Tile(tileNode))?.ToArray();
      82. }
      83. static public Garden FromHtml(string gardenHtml)
      84. {
      85. var document = gardenHtml.HAPDocumentFromHtml();
      86. return new Garden(document.DocumentNode);
      87. }
      88. }
      89. void ClickOnEachTile(
      90. IDocument Document,
      91. IEnumerable<Tile> setTileToClick)
      92. {
      93. if(null == setTileToClick)
      94. return;
      95. foreach(var tile in setTileToClick)
      96. {
      97. var tileElement = Document.GetElementFromXPath("//div[@id='" + tile.tileNode?.Id + "']");
      98. tileElement?.click();
      99. // delay of random length
      100. Host.Delay(333 + (int)(Host.GetTimeContinuousMilli() % 1111));
      101. }
      102. }
      103. Garden GardenFromDocument(IDocument Document)
      104. {
      105. var gardenElement = Document?.GetElementFromXPath("//div[@id='gardenDiv']");
      106. Host.Log("gardenElement: " + gardenElement);
      107. var garden = Garden.FromHtml(gardenElement?.outerHTML);
      108. Host.Log("garden.tile.count: " + garden?.setTile?.Length);
      109. return garden;
      110. }
      111. for(var RundeIndex = 0; ; ++RundeIndex)
      112. {
      113. Host.Log("starte Runde " + RundeIndex);
      114. var Document = Connection?.Document?.Result;
      115. Host.Log("Document: " + Document);
      116. var garden = GardenFromDocument(Document);
      117. var setTileToHarvest = garden?.setTile?.Where(t => t.readyToHarvest)?.ToArray();
      118. Host.Log("Kacheln fertig zum ernten: " + setTileToHarvest?.Length);
      119. if(0 < setTileToHarvest?.Length)
      120. {
      121. Host.Log("beginne ernte....");
      122. ButtonErnten(Document)?.click();
      123. ClickOnEachTile(Document, setTileToHarvest);
      124. }
      125. garden = GardenFromDocument(Document);
      126. var setTileToPlant = garden?.setTile?.Where(t => t.readyToPlant)?.ToArray();
      127. Host.Log("Kacheln verfügbar zum pflanzen: " + setTileToPlant?.Length);
      128. if(0 < setTileToPlant?.Length)
      129. {
      130. Host.Log("beginne pflanzen....");
      131. ButtonPflanzen(Document)?.click();
      132. ClickOnEachTile(Document, setTileToPlant);
      133. }
      134. garden = GardenFromDocument(Document);
      135. var setTileToWater = garden?.setTile?.Where(t => t.readyToWater)?.ToArray();
      136. Host.Log("Kacheln zu gießen: " + setTileToWater?.Length);
      137. if(0 < setTileToWater?.Length)
      138. {
      139. Host.Log("beginne gießen....");
      140. ButtonGiessen(Document)?.click();
      141. ClickOnEachTile(Document, setTileToWater);
      142. }
      143. var TimeToRepeat = Host.GetTimeContinuousMilli() % RundePauseMax + RundePauseMin;
      144. Host.Log("Runde " + RundeIndex + " abgeschlossen. Nächste Runde in " + TimeToRepeat + " sekunden.");
      145. Host.Delay((int)TimeToRepeat * 1000);
      146. }

      Dateien

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „0ptimist“ ()