Zurück zum Blog
Anleitungen
Raluca PenciucLast updated on Mar 31, 20268 min read

So scrapen Sie YouTube wie ein Profi: Ein umfassender Leitfaden

So scrapen Sie YouTube wie ein Profi: Ein umfassender Leitfaden

Benötigen Sie Daten von einer Website, aber die verfügbaren APIs reichen einfach nicht aus? Web-Scraping ist die Lösung, nach der Sie gesucht haben. Mit Web-Scraping können Sie Daten umfassender und flexibler von einer Website extrahieren.

In diesem Artikel tauchen wir in die Welt des Web Scraping ein und schauen uns genauer an, wie man YouTube, eine der beliebtesten Videoplattformen, scrapt. Zwar stellt YouTube eine API für den Zugriff auf Daten bereit, doch Web Scraping bietet eine größere Bandbreite an Möglichkeiten, um Daten aus YouTube-Kanälen zu extrahieren.

Wir beginnen mit der Einrichtung einer Entwicklungsumgebung und den Voraussetzungen für Web Scraping und gehen dann zum eigentlichen Prozess des Scrapings von YouTube über. Dabei geben wir Ihnen Tipps zur Verbesserung Ihrer Web-Scraping-Fähigkeiten und erörtern, warum die Verwendung eines professionellen Scrapers eine bessere Wahl sein kann als die Entwicklung eines eigenen.

Am Ende dieses Artikels verfügen Sie über das Wissen und die Fähigkeiten, um Daten von YouTube wie ein Profi effektiv zu scrapen!

Voraussetzungen

Zunächst einmal müssen Sie sicherstellen, dass Node.js auf Ihrem Rechner installiert ist. Falls Sie es noch nicht haben, besuchen Sie die offizielle Node.js-Website und folgen Sie den Anweisungen für Ihr jeweiliges Betriebssystem. Beachten Sie unbedingt, dass Sie die Long Term Support (LTS)-Version herunterladen sollten, um sicherzustellen, dass Sie eine stabile und unterstützte Version haben.

Als Nächstes musst du den Node.js Package Manager (NPM) installieren. Dieser sollte automatisch mit der Installation von Node.js mitgeliefert werden, aber es ist immer gut, dies noch einmal zu überprüfen.

Was Ihre Entwicklungsumgebung angeht, können Sie jede beliebige IDE verwenden. Ich werde in diesem Tutorial Visual Studio Code verwenden, da es flexibel und benutzerfreundlich ist, aber jede IDE ist geeignet. Erstellen Sie einfach einen neuen Ordner für Ihr Projekt und öffnen Sie ein Terminal. Führen Sie den folgenden Befehl aus, um ein neues Node.js-Projekt einzurichten:

npm init -y

Dadurch wird eine Standarddatei „package.json“ für Ihr Projekt erstellt. Sie können diese Datei jederzeit an Ihre Bedürfnisse anpassen.

Nun ist es an der Zeit, TypeScript und die Typdefinitionen für Node.js zu installieren. TypeScript ist in der JavaScript-Community wegen seiner optionalen statischen Typisierung sehr beliebt, da diese hilft, Typfehler in Ihrem Code zu vermeiden. Um es zu installieren, führen Sie den folgenden Befehl aus:

npm install typescript @types/node --save-dev

Um zu überprüfen, ob die Installation erfolgreich war, können Sie den folgenden Befehl ausführen:

npx tsc --version

Zuletzt müssen Sie eine Konfigurationsdatei namens „tsconfig.json“ im Stammverzeichnis Ihres Projektverzeichnisses erstellen. Diese Datei definiert die Compiler-Optionen für Ihr Projekt. Wenn Sie mehr über diese Datei und ihre Eigenschaften erfahren möchten, lesen Sie die offizielle TypeScript-Dokumentation.

Alternativ können Sie den folgenden Code kopieren und in Ihre tsconfig.json-Datei einfügen:

{

   "compilerOptions": {

       "module": "commonjs",

       "esModuleInterop": true,

       "target": "es2017",

       "moduleResolution": "node",

       "sourceMap": true,

       "outDir": "dist"

   },

   "lib": ["es2015"]

}

Für den Scraping-Prozess verwende ich Puppeteer, eine Headless-Browser-Bibliothek für Node.js, mit der Sie einen Webbrowser steuern und programmgesteuert mit Websites interagieren können. Um Puppeteer zu installieren, führen Sie den folgenden Befehl aus:

npm install puppeteer

Extrahieren der Daten

Für diese Anleitung werde ich einen YouTube-Kanal mit DevOps-bezogenen Tutorials scrapen: https://www.youtube.com/@TechWorldwithNana/videos. Die Daten, die mich dabei besonders interessieren, sind:

  • das Profilbild des Kanals
  • der Name des Kanals
  • den Nutzernamen des Kanals
  • die Anzahl der Abonnenten des Kanals
  • die Titel aller Videos
  • die Anzahl der Aufrufe aller Videos
  • die Miniaturansichten aller Videos
  • die URLs aller Videos

Ich werde Screenshots für jeden Abschnitt einfügen und mich auf CSS-Selektoren stützen, um die Daten im DOM zu finden. Dies ist die einfachste und unkomplizierteste Methode, es sei denn, die Zielwebsite ist dafür bekannt, eine instabile DOM-Struktur zu haben.

Wenn du noch keine Erfahrung mit CSS-Selektoren hast, schau dir dieses umfassende Spickzettel an, mit dem du im Handumdrehen loslegen kannst.

Beginnen wir damit, einen Ordner „src“ und die Datei „index.ts“ anzulegen, in der wir den Code schreiben werden. Öffnen wir nun einfach einen Browser und navigieren wir zur Ziel-URL:

import puppeteer from 'puppeteer';

async function scrapeChannelData(channelUrl: string): Promise<any> {

    // Launch Puppeteer

    const browser = await puppeteer.launch({

        headless: false,

    	  args: ['--start-maximized'],

    	  defaultViewport: null

    });

    // Create a new page and navigate to the channel URL

    const page = await browser.newPage();

    await page.goto(channelUrl);

    // Close the browser

    await browser.close();

}

scrapeChannelData("https://www.youtube.com/@TechWorldwithNana/videos");

Zum visuellen Debuggen öffne ich den Browser im Nicht-Headless-Modus. Wenn du vorhast, deinen Anwendungsfall in großem Maßstab zu erweitern, empfehle ich dir, den Headless-Modus auszuprobieren.

Um das Skript auszuführen, müssen Sie es zunächst kompilieren und dann die generierte JavaScript-Datei ausführen. Um die Sache zu vereinfachen, können wir in der Datei „package.json“ ein Skript definieren, das diese beiden Schritte für uns übernimmt. Bearbeiten Sie einfach den Abschnitt „scripts“ Ihrer „package.json“-Datei wie folgt:

"scripts": {

    "test": "npx tsc && node dist/index.js"

},

Jetzt müssen Sie zum Ausführen Ihres Codes nur noch den folgenden Befehl ausführen:

npm run test

Schon beim ersten Durchlauf fällt ein erstes Problem auf: der Vollbild-Dialog zur Cookie-Zustimmung, der uns den Zugriff auf die Daten verhindert.

Glücklicherweise ist er im Viewport sichtbar, sodass wir die Entwicklertools nutzen können, um seine Kennung zu finden und darauf zu klicken.

Wir fügen außerdem eine zusätzliche Wartezeit hinzu, damit die Navigation abgeschlossen werden kann. Der Code sieht dann wie folgt aus:

await page.waitForSelector('button[aria-label="Accept all"]')

await page.click('button[aria-label="Accept all"]')

await page.waitForTimeout(10 * 1000)

Kanalinformationen

Im folgenden Screenshot sind die Abschnitte hervorgehoben, die die Kanaldaten enthalten, die wir extrahieren möchten.

Eine gute Faustregel für die einfache Lokalisierung der HTML-Elemente ist die Wahl eindeutiger CSS-Selektoren. Um beispielsweise den Kanal-Avatar zu extrahieren, wähle ich das benutzerdefinierte HTML-Element yt-img-shadow mit der ID avatar. Anschließend extrahiere ich das src-Attribut seines untergeordneten img-Elements.

const channelAvatar = await page.evaluate(() => {

    const el = document.querySelector('yt-img-shadow#avatar > img');

    return el ? el.getAttribute('src') : null;

});

console.log(channelAvatar)

Für den Kanalnamen verwenden wir den Textinhalt des Elements yt-formatted-string mit der ID text.

const channelName = await page.evaluate(() => {

    const el = document.querySelector('yt-formatted-string#text');

    return el ? el.textContent : null;

});

console.log(channelName)

Um den Kanal-Handle zu erhalten, suchen wir das Element yt-formatted-string mit der ID channel-handle und extrahieren dessen Textinhalt.

const channelHandle = await page.evaluate(() => {

    const el = document.querySelector('yt-formatted-string#channel-handle');

    return el ? el.textContent : null;

});

console.log(channelHandle)

Und schließlich müssen wir für die Anzahl der Kanalabonnenten lediglich auf das Element „yt-formatted-string“ mit der ID „subscriber-count“ zugreifen und dessen Textinhalt abrufen.

const subscriberCount = await page.evaluate(() => {

    const el = document.querySelector('yt-formatted-string#subscriber-count');

    return el ? el.textContent : null;

});

console.log(subscriberCount)

Wenn Sie das Skript erneut ausführen, sollten Sie die folgende Ausgabe sehen:

https://yt3.googleusercontent.com/kXyR8Aa32KXnZWVdkAFUYK5utM752kSJPHGtYiJ4ev6BmdFHi-dl1EFbI3TogmHBjszwc7m2=s176-c-k-c0x00ffffff-no-rj

TechWorld with Nana

@TechWorldwithNana

709K subscribers

Videodaten

Weiter geht es mit den Videodaten; ich habe auch die relevanten Abschnitte des HTML-Dokuments hervorgehoben. Hier müssen wir eine Liste von Elementen extrahieren, also schauen wir uns zuerst die übergeordneten Container an und durchlaufen dann jeden einzelnen davon.

Wir verfolgen denselben Ansatz wie im vorherigen Abschnitt: Wir wählen einige eindeutige CSS-Selektoren aus, um die benötigten Daten zu finden, wobei wir uns auf deren IDs konzentrieren. Der Code sollte in etwa so aussehen:

const videos = await page.evaluate(() => {

    const videosEls = Array.from(document.querySelectorAll('div#dismissible'))

    return videosEls.map(video => {

        const titleEl = video.querySelector('yt-formatted-string#video-title');

        const viewsEl = video.querySelector('div#metadata-line > span');

        const thumbnailEl = video.querySelector('yt-image.ytd-thumbnail > img');

        const locationEl = video.querySelector('a#thumbnail');

        return {

            title: titleEl ? titleEl.textContent : null,

            views: viewsEl ? viewsEl.textContent : null,

            thumbnail: thumbnailEl ? thumbnailEl.getAttribute('src') : null,

            location: locationEl ? locationEl.getAttribute('href') : null

        }

    })

})

console.log(videos)

Wenn du den Code ausführst, sollte die Ausgabe eine Liste von JavaScript-Objekten sein. Jedes davon sollte den Titel, die Anzahl der Aufrufe, das Vorschaubild und die Position jedes Videoelements auf der Seite enthalten.

Sie werden jedoch feststellen, dass Ihre Liste ab einem bestimmten Punkt wie folgt aussieht:

{

    title: 'GitLab CI/CD Full Course released - CI/CD with Docker | K8s | Microservices!',  

    views: '114K views',

    thumbnail: null,

    location: '/watch?v=F7WMRXLUQRM'

},

{

    title: 'Kubernetes Security Best Practices you need to know | THE Guide for securing your K8s cluster!',

    views: '103K views',

    thumbnail: null,

    location: '/watch?v=oBf5lrmquYI'

},

{

    title: 'How I learn new technologies as a DevOps Engineer (without being overwhelmed)',

    views: '366K views',

    thumbnail: null,

    location: '/watch?v=Cthla7KqU04'

},

{

    title: 'Automate your Multi-Stage Continuous Delivery and Operations | with Keptn',	 

    views: '59K views',

    thumbnail: null,

    location: '/watch?v=3EEZmSwMXp8'

},

Obwohl die Videoelemente weiterhin ein Miniaturbild haben und sich der CSS-Selektor nicht geändert hat, ist der extrahierte Wert null. Dies geschieht in der Regel, wenn eine Website Lazy Loading implementiert, was bedeutet, dass der Rest der Liste geladen wird, während Sie zum Ende der Seite scrollen.

Um dieses Problem zu lösen, müssen wir unser Skript einfach anweisen, auf der Kanalseite nach unten zu scrollen.

async function autoScroll(page: any, scroll_number: number): Promise<any> {

    await page.evaluate(async (scroll_number: number) => {

        await new Promise((resolve) => {

            let totalHeight = 0;

        	const timer = setInterval(() => {

                const scrollHeight = window.innerHeight * scroll_number;

                window.scrollBy(0, window.innerHeight);

                totalHeight += window.innerHeight;

                if (totalHeight > scrollHeight) {

                    clearInterval(timer);

                	  resolve(true);

                }

        	}, 1000);

    	  });

    }, scroll_number);

}

Diese Funktion nimmt als Parameter unsere geöffnete Seite und eine Anzahl von Scrollbewegungen entgegen. Anschließend versucht sie, die Entfernung, die der Fensterhöhe entspricht, so oft zu scrollen, wie es der Parameter scroll_number vorgibt. Diese Bewegungen werden alle 1 Sekunde ausgeführt.

Rufe nun einfach die Funktion vor dem Code-Schnipsel auf, der die Liste der Videos extrahiert.

await autoScroll(page, 10)

await page.waitForTimeout(2 * 1000)

Ich habe eine zusätzliche Wartezeit von 2 Sekunden hinzugefügt, damit die Website Zeit hat, die letzten Elemente der Liste vollständig zu laden. Wenn du das Skript erneut ausführst, wirst du zunächst sehen, wie die Scrollbewegungen ablaufen, und dann, dass alle Elemente in der Liste einen Thumbnail-Wert haben.

Vermeiden Sie es, blockiert zu werden

Auch wenn die Anleitung bis zu diesem Punkt mühelos erschien, gibt es mehrere Herausforderungen, denen Web-Scraper normalerweise begegnen. Insbesondere YouTube setzt viele Anti-Bot-Techniken ein, um zu verhindern, dass automatisierte Skripte seine Daten extrahieren.

Einige dieser Techniken sind:

  • CAPTCHAs: Das Lösen von CAPTCHAs kann für einen Scraper zeitaufwändig und schwierig sein, was als Abschreckung für Bots dienen kann.
  • JavaScript-Herausforderungen: Dazu können Aufgaben wie das Lösen von Rechenaufgaben, das Ausfüllen eines CAPTCHAs oder das Auffinden eines bestimmten Elements auf der Seite gehören. Ein Bot, der die Herausforderung nicht bewältigen kann, wird erkannt und möglicherweise blockiert.
  • User-Agent-Prüfungen: YouTube überprüft möglicherweise die User-Agent-Zeichenfolge eingehender Anfragen, um festzustellen, ob diese von einem Browser oder einem Scraper stammen. Wird die User-Agent-Zeichenfolge nicht als gültiger Browser erkannt, wird die Anfrage möglicherweise blockiert.
  • IP-Blockierung: YouTube kann Anfragen von bestimmten IP-Adressen blockieren, von denen bekannt ist, dass sie mit Bots oder Scraping-Aktivitäten in Verbindung stehen.
  • Honeypots: YouTube verwendet möglicherweise Honeypots, also versteckte Elemente auf der Seite, die nur für Bots sichtbar sind. Wird ein Bot erkannt, der mit einem Honeypot interagiert, kann er identifiziert und blockiert werden.

Die Behandlung jedes einzelnen dieser Probleme kann die Komplexität und die Kosten Ihres Scraper-Codes erheblich erhöhen. Hier spielen Scraping-APIs eine wichtige Rolle, da sie diese Probleme standardmäßig bewältigen und zu einem günstigeren Preis verfügbar sind.

WebScrapingAPI ist ein Beispiel für einen solchen Dienst. Er bietet leistungsstarke Funktionen, um Bot-Erkennungstechniken zu umgehen und die benötigten Daten präzise zu extrahieren.

Wir können WebScrapingAPI schnell ausprobieren, indem wir das Node.js-SDK in unserem kleinen Projekt installieren:

npm i webscrapingapi

Besuchen Sie nun die Homepage, um ein Konto zu registrieren. Sie erhalten dann automatisch Ihren API-Schlüssel und eine kostenlose Testversion. Den API-Schlüssel finden Sie im Dashboard und verwenden ihn zur Authentifizierung Ihrer Anfragen an die API:

Und das war’s schon, Sie können mit dem Programmieren beginnen!

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage(target_url: string) {

    const api_params = {

        'render_js': 1,

    	  'proxy_type': 'datacenter',

    	  'country': 'us',

    	  'timeout': 60000,

    	  'js_instructions': JSON.stringify([

            {

                action: "click",

                selector: 'button[aria-label="Accept all"]',

                timeout: 10000

         	}

    	  ]),

    	  'extract_rules': JSON.stringify({

        	avatar: {

                selector: "yt-img-shadow#avatar > img",

                output: "@src",

        	},

        	name: {

                selector: "yt-formatted-string#text",

                output: "text",

        	},

        	handle: {

                selector: "yt-formatted-string#channel-handle",

                output: "text",

        	},

        	subscribers: {

                selector: "yt-formatted-string#subscriber-count",

                output: "text",

        	},

        	videoTitles: {

                selector: "yt-formatted-string#video-title",

                output: "text",

                all: "1"

        	},

        	videoViews: {

                selector: "div#metadata-line > span",

                output: "text",

                all: "1"

        	},

        	videoThumbnails: {

                selector: "yt-image.ytd-thumbnail > img",

                output: "@src",

                all: "1"

        	},

        	videoLocations: {

                selector: "a#thumbnail",

                output: "@href",

                all: "1"

        	},

        })

    }

    const response = await client.get(target_url, api_params);

    if (response.success) {

        console.log(response.response.data);

    } else {

        console.log(response.error.response.data);

    }

}

exampleUsage("https://www.youtube.com/@TechWorldwithNana/videos");

Wir haben den zuvor beschriebenen Algorithmus und die CSS-Selektoren auf die API übertragen. Der Parameter „js_instructions“ übernimmt die Handhabung des Cookie-Fensters, indem er auf die Schaltfläche „Alle akzeptieren“ klickt. Schließlich übernimmt der Parameter „extract_rules“ die Datenextraktion.

const scroll_number = 10

let scroll_index = 0

for (let i = 0; i < scroll_number; i++) {

    const js_instructions_obj = JSON.parse(api_params.js_instructions)

    js_instructions_obj.push({

        action: "scrollTo",

        selector: `ytd-rich-grid-row.ytd-rich-grid-renderer:nth-child(${scroll_index + 3})`,

        block: "end",

     	  timeout: 1000

    })

    api_params.js_instructions = JSON.stringify(js_instructions_obj)

    scroll_index += 3

}

Denken Sie daran, kurz vor dem Absenden der Anfrage auch die Scroll-Logik anzupassen. Diese unterscheidet sich geringfügig, da wir die API anweisen, zehnmal zur dritten Zeile der Videos zu scrollen.

Fazit

In diesem Artikel haben wir das spannende Gebiet des Web-Scrapings erkundet und gelernt, wie man mit Node.js und Puppeteer Daten von YouTube scrapt. Wir haben die notwendigen Vorbereitungen für das Web-Scraping sowie den Prozess der Datenextraktion aus YouTube-Kanälen behandelt.

Web-Scraping kann ein unglaublich nützliches Werkzeug für den Zugriff auf Daten von Websites sein. Dennoch ist es wichtig, die verschiedenen Herausforderungen und Überlegungen zu berücksichtigen, die damit einhergehen. Dazu können CAPTCHAs, dynamische Inhalte, Ratenbegrenzungen oder Änderungen an der Website gehören.

Wenn Sie darüber nachdenken, Daten von YouTube oder einer anderen Website zu scrapen, ist es unerlässlich, die Vor- und Nachteile abzuwägen und zu entscheiden, ob Web-Scraping die beste Lösung für Ihre Anforderungen ist. In manchen Fällen kann die Nutzung einer API oder der Kauf von Daten aus einer seriösen Quelle eine geeignetere Option sein als das Scraping.

Unabhängig davon, für welchen Ansatz Sie sich entscheiden, ist es entscheidend, die Nutzungsbedingungen und Urheberrechtsgesetze zu beachten, die für die Daten gelten, auf die Sie zugreifen. Und wenn Sie sich doch dazu entschließen, Daten von YouTube zu scrapen, denken Sie daran, einen professionellen Scraper zu verwenden, um sicherzustellen, dass Sie auf sichere und effiziente Weise genaue, aktuelle Daten erhalten.

Ich hoffe, dieser Artikel war hilfreich für Sie auf Ihrem Weg, mehr über Web-Scraping und das Scrapen von YouTube-Daten zu erfahren!

Über den Autor
Raluca Penciuc, Full-Stack-Entwickler @ WebScrapingAPI
Raluca PenciucFull-Stack-Entwickler

Raluca Penciuc ist Full-Stack-Entwicklerin bei WebScrapingAPI. Sie entwickelt Scraper, verbessert Umgehungsstrategien und findet zuverlässige Wege, um die Erkennung auf Zielwebsites zu verringern.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.