Zeitersparnis durch Puppeteer: Manuelle-Prozesse Automatisieren

Rone Derki, 17. August 2023
Lesezeit: 8 Minuten

In einem unserer Kundenprojekte standen wir vor der Situation, dass eine wiederholende und zeitaufwendige Durchführung einer Aufgabe enorme Kapazitäten einband. Die Aufgabe erforderte wiederholende Handlungen: das Öffnen von Webseiten, die Navigation durch verschiedene Ansichten und schließlich das Aufnehmen von Screenshots. Die Notwendigkeit, den Prozess zu automatisieren erforderte eine innovative Lösung um die Effizienz erheblich zu steigern.

Um eine optimale Lösung zu finden, haben wir die Bibliothek Puppeteer eingeführt. In diesem Blog-Beitrag erklären wir was Puppeteer ist, welche Vorteile das Tool für unser Kundenprojekt mit sich brachte und wie die Bibliothek angewendet wird.

Was ist Puppeteer?

Puppeteer ist eine Node.js-Bibliothek, die von Google entwickelt wurde um die Steuerung und Automatisierung des Chrome-Browsers zu ermöglichen. Mit Puppeteer können wir Webseiten programmgesteuert aufrufen, mit ihnen interagieren und Daten extrahieren. Das Tool simuliert das Verhalten eines Benutzers, indem es Mausklicks, Tastatureingaben und Navigation durchführt, was es zu einem idealen Werkzeug für die Automatisierung von Prozessen in Webapplikationen macht.

Vorteile von Puppeteer

  • Zeitersparnis. Wiederholte manuelle Aufgaben werden automatisiert.
  • Fehlerfreie Anwendung. User müssen keine fehleranfälligen Aktionen manuell durchführen, sondern können diese automatisieren. Fehlerquellen werden eliminiert und die Anwendung führt zu einem zuverlässigen Ergebnis.
  • Skalierbarkeit. Die Skalierbarkeit der Bibliothek ermöglicht die gleichzeitige Verarbeitung mehrerer Aufgaben. Dies ist besonders nützlich, wenn es darum geht, eine große Anzahl von Aktionen auszuführen oder komplexe Prozesse parallel zu bewältigen.

Hervorzuheben ist, dass die einmalige Nutzung des Puppeteers noch keine Zeitersparnis bietet, sondern der Vorteil im vielfach-ausgeführten Prozess liegt. Die Automatisierung wird effizient und präzise ausgeführt. Maßgeschneiderte Arbeitsabläufe können definiert werden, die nicht nur Zeit sparen, sondern auch eine hohe Qualität und Verlässlichkeit der Ergebnisse gewährleisten.

Implementierung

Die Implementierung erfolgt sowohl auf dem Client als auch auf dem Server.

Frontend - Client:

Im Frontend wird die Methode makeScreenshotAutomatically verwendet, um die ausgewählten Ansichten, die der User ausgewählt hat, an das Backend zu senden, damit der Prozess im Hintergrund startet. In unserem Anwendungsbeispiel nimmt die Methode Parameter wie die Projekt-ID, ausgewählte Ansichten (einzel, mehrere Manuell ausgewählt, oder ein ganzer Ordner) an. Anhand dieser Daten wird die Anfrage an das Backend vorbereitet und gestartet.

Copy
public makeScreenshotAutomatically(projectId: number, selectedViews: IterableIterator<...>, folder: Folder, view: number) {
   ...

   let isFolder = folder instanceof Folder;

   of(true).pipe(
      switchMap(() => isFolder
         ? this.foldersService.getFolders(folder.folder_info.id, this.filterWrapper).pipe(map((folder: Folder) => folder?.views?.map(i => i.id)))
                : of([view])
         ),
      switchMap((viewIds: number[]) => this.puppeteerService.makeScreenshots(viewIds))
  ).subscribe();
}

Backend - Client:

Das Backend empfängt die Daten aus dem Frontend und speichert sie in einem Model, das alle relevanten Informationen für Puppeteer enthält. Das Model enthält beispielsweise Felder wie Benutzername, Passwort, URL und die gewünschten Ansichten. Die Verwendung eines Models ermöglicht es, die Daten logisch zu gruppieren und in einer klaren Struktur zu organisieren. Anschließend wird das Model an den Server gesendet, wo die Bibliothek Puppeteer ausgeführt wird.

Um zeitaufwendige Anfragen zu vermeiden, erfolgt die Ausführung asynchron. Durch die asynchrone Verarbeitung kann das Backend mehrere Aufgaben gleichzeitig bewältigen, ohne durch langwierige Aufgaben blockiert zu werden. Wenn das Backend synchron auf die Beendigung dieser zeitaufwendigen Aktionen warten würde, könnte dies die Reaktionsfähigkeit der Benutzeroberfläche beeinträchtigen und die Benutzererfahrung negativ beeinflussen.

Server:

Nach dem die Anfrage vom Server erhalten wurde, wird Puppeteer ausgeführt. Puppeteer ruft die Webseite auf, führt die notwendigen Schritte wie das Anmelden, das Navigieren zum Modell und das Warten auf das vollständige Laden durch. Anschließend erstellt Puppeteer automatisch einen Screenshot des Modells. Dieser Schritt wird in den meisten Fällen mehrmals ausgeführt, da in der Regel eine große Liste von ausgewählten Modellen verarbeitet wird.

Copy
  async makeScreenshotOfProjectModel(puppeteerRequestModel: PuppeteerRequestModel) {
     ...
     for (let i = 0; i < viewIds.length; i++) {
        try {
           ...
           await page.waitForSelector(`.search`, {visible: true});
           await page.focus('.search');
           await page.evaluate(() => {
              const input = document.querySelector('.search') as HTMLInputElement;
              if (input.value !== '') {
                 input.value = '';
              }});
              await page.keyboard.type(String(viewIds[i]));
              await new Promise(resolve => setTimeout(resolve, 2000));

              ...
                    
              try {
                 await page.waitForSelector('div.isloaded', {timeout: 180000});
              } catch (error: any) {
                 error.message = 'Model konnte nicht geladen werden';
                 throw error;
              }

              ...
                    
              this.successful++;
           } catch (error: any) {
              this.failed++;
              this.viewIdsIdFailed.push(viewIds[i]);
           }
        }  
     } finally {

        this.resultMessage = {...};
     }

Anschließend speichern wir die Ergebnisse der Ausführung, darunter die Anzahl der erstellten Screenshots, wie viele erfolgreich waren und wie viele fehlgeschlagen haben. Auf diese Weise kann der Benutzer den Gesamtablauf nachverfolgen und erhält einen Überblick über die durchgeführten Aktionen. Die Ergebnisse werden dann an das Backend zurückgesendet, das sie an das Frontend weiterleitet und dem Benutzer anzeigt.

Fazit:

Dank der nahtlosen Integration von Puppeteer in unser Kundenprojekt konnten wir erfolgreich einen zeitaufwendigen, manuellen Prozess automatisieren.

Anzumerken ist, dass dieser Prozess im Produktivbetrieb tausende Male durchlaufen wird, wodurch die Serverinstanz effizient und zuverlässig viele wiederkehrende Aufgaben bewältigen kann. Obwohl der ursprüngliche Prozess an sich nicht als zeitaufwendig betrachtet werden kann, wird er erst zeitaufwendig, wenn er in hoher Wiederholungsfrequenz ausgeführt wird.

Die gesteigerte Effizienz und die verbesserte Genauigkeit, die wir durch die Implementierung erzielen konnten, haben dazu beigetragen, unser Kundenprojekt effektiver zu gestalten. Die Fähigkeit, den Prozess zu automatisieren und in beliebiger Menge zu wiederholen, führt nicht nur zu gesteigerter Produktivität, sondern auch zu erheblicher Zeitersparnis für unsere Kunden.

author image
Rone Derki
Student Wirtschaftsinformatik, 6. Semester
Durch die Anwendung von Puppeteer im Rahmen meines Praktikums hatte ich die Möglichkeit, eigenständig in die Welt der Prozessautomatisierung und JavaScript einzutauchen. Hierbei konnte ich nicht nur meine Fähigkeiten in der JavaScript-Programmierung vertiefen, sondern auch neue Technologien kennenlernen und die erworbenen Kenntnisse aus meinem Praktikum effektiv einsetzen.