Wie man mit Python wichtige YouTube-Daten abgreift

Bemerkungen: 0

YouTube-Ersteller müssen die Leistung ihrer Videos bewerten; die Analyse positiver und negativer Kommentare und der Vergleich ihrer Inhalte mit anderen in der gleichen oder einer anderen Kategorie sind unerlässlich.

Das manuelle Durchsuchen der geposteten Videos kann für die Ersteller mühsam und zeitaufwändig sein. Genau hier wird ein YouTube-Skript zum Scraping von unschätzbarem Wert. In diesem Leitfaden werden wir ein YouTube-Skript entwickeln, das den Prozess der Datenerfassung automatisiert.

Erstellen eines Scrapers zum Extrahieren von Daten aus YouTube

Damit das Skript richtig funktioniert, müssen wir einige Pakete installieren. Das erste zu installierende Paket ist selenium-wire, eine Erweiterung von Selenium, die eine korrekte Proxy-Konfiguration ermöglicht, sowie Selenium selbst für wichtige Klassen und Module. Um diese Pakete zu installieren, führen Sie den folgenden Befehl in Ihrer Kommandoschnittstelle aus:

pip install selenium-wire selenium blinker==1.7.0

Konzentrieren wir uns nun auf die Einfuhren.

Schritt 1: Bibliotheken und Pakete importieren

In dieser Phase ist es wichtig, die Bibliotheken und Pakete zu importieren, die in unserem Skript für die Interaktion mit den Web-Elementen verwendet werden sollen. Außerdem sollten wir Module für die Datenverarbeitung und das Laufzeitmanagement einbinden, um eine effiziente Ausführung des Skripts zu gewährleisten.

from selenium.webdriver.chrome.options import Options
from seleniumwire import webdriver as wiredriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import json
import time

Das json-Modul hilft bei der Konvertierung der extrahierten Daten in korrekt formatierte JSON-Daten und gewährleistet eine optimale Datendarstellung. Trotz der Maskierung unserer IP ist das Zeitmodul unerlässlich, um Zufälligkeit in die Aktionen einzubringen und das Auftreten von skriptähnlichem Verhalten zu verhindern.

Darüber hinaus ist dieses Modul wichtig, um sicherzustellen, dass die Elemente, die wir zum Extrahieren von Daten aus der Seite benötigen, geladen sind. Die übrigen Importe bestehen aus notwendigen Klassen oder Untermodulen, die bestimmte Aktionen ausführen und in den folgenden Abschnitten des Codes näher erläutert werden.

Schritt 2: Selenium Chrome Driver einrichten

Immer wenn Sie eine Selenium-Instanz mit einem Skript in Python ausführen, verwendet das Skript unsere IP-Adresse für die Aktivität, die wir durchführen möchten. Das ist gefährlich, vor allem für Websites wie YouTube, die strenge Richtlinien gegen das Scraping von Informationen von ihrer Website haben (Sie können die Robots-Datei für eine bessere Referenz einsehen). Die Folge davon könnte sein, dass Ihre IP-Adresse vorübergehend für den Zugriff auf YouTube-Inhalte gesperrt wird.

Um all das zu vermeiden, müssen wir ein paar Dinge tun. Wir müssen 3 Variablen erstellen, um die Details des Proxys zu speichern, über den wir auf die Seite zugreifen würden. Dann erstellen wir eine Optionsvariable, chrome_options, die wir an die Chrome WebDriver-Instanz übergeben, damit Selenium weiß, welchen Proxy es beim Scraping verwenden soll. Wir übergeben die Proxy-Details als Argumente für chrome_options und unser Proxy ist gesetzt.

# Geben Sie die Adresse des Proxyservers mit Benutzernamen und Passwort an
proxy_address = ""
proxy_username = ""
proxy_password = ""
# Einrichten der Chrome-Optionen mit dem Proxy und der Authentifizierung
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')
# Erstellen einer WebDriver-Instanz mit selenium-wire
driver = wiredriver.Chrome(options=chrome_options)

Schritt 3: Extrahieren der Informationen von der YouTube-Videoseite

Erstellen Sie eine Variable namens "youtube_url_to_scrape", um die URL der YouTube-Landingpage zu speichern. Diese Variable wird dann in der Methode "driver.get()" verwendet, um Selenium anzuweisen, eine bestimmte Seite zum Scrapen zu öffnen. Durch die Ausführung dieser Aktion wird ein separates Chrome-Fenster geöffnet, wenn das Skript ausgeführt wird.

youtube_url_to_scrape = ""
# Führen Sie Ihre Selenium-Automatisierung mit den erweiterten Möglichkeiten von selenium-wire durch.
driver.get(youtube_url_to_scrape)

Als nächstes definieren wir die Funktion "extract _information()", die, wie der Name schon sagt, die notwendigen Informationen aus der Seite extrahiert.

Es ist wichtig, sicherzustellen, dass alle Elemente der Seite geladen werden. Dazu verwenden wir die Klasse WebDriverWait, um das Skript mindestens so lange anzuhalten, bis die Schaltfläche "more" verfügbar ist und angeklickt wird, die unter der Variable "element" implementiert ist. Sobald diese verfügbar ist, führt Selenium eine JavaScript-Klickaktion aus, die den Zugriff auf die vollständige Beschreibung des Videos ermöglicht.

Um das bereits erwähnte Problem der dynamischen Kommentare anzugehen, implementieren wir eine Lösung, die alle damit verbundenen Probleme beseitigt. Mithilfe der Klasse "Actions" und des Moduls "Time" scrollen wir alle 10 Sekunden zweimal nach unten und stellen sicher, dass so viele Kommentare wie möglich erfasst werden. Dieser proaktive Ansatz schützt vor potenziellen Engpässen im Zusammenhang mit dynamisch geladenen Inhalten.

def extract_information() -> dict:
   try:
       element = WebDriverWait(driver, 15).until(
           EC.presence_of_element_located((By.XPATH, '//*[@id="expand"]'))
       )

       element.click()

       time.sleep(10)
       actions = ActionChains(driver)
       actions.send_keys(Keys.END).perform()
       time.sleep(10)
       actions.send_keys(Keys.END).perform()
       time.sleep(10)

Es gibt verschiedene Möglichkeiten, mit Selenium Webdriver nach Elementen zu suchen. Sie können nach ID, CLASS_NAME, XPATH, etc. suchen. In diesem Leitfaden werden wir eine Kombination und nicht nur eine Methode verwenden.

XPATH ist ein komplizierteres, aber musterbasiertes System zum Auffinden von Variablen beim Scraping. Es gilt als das komplizierteste; Chrome hat es jedoch einfach gemacht.

Wenn Sie den Code mit dem Inspektionstool von Chrome überprüfen, klicken Sie einfach mit der rechten Maustaste, um den XPATH zu kopieren. Nach dem Kopieren können Sie die Funktion "find_elements" verwenden, um alle Elemente zu identifizieren, die die gewünschten Informationen enthalten, z. B. den Videotitel, die Beschreibung usw.

Es ist wichtig zu beachten, dass bestimmte Elemente auf der Seite ähnliche Attribute haben können, was dazu führen kann, dass der Aufruf von `find_elements()` eine Liste statt eines Strings zurückgibt. In solchen Fällen müssen Sie die Liste untersuchen, um den Index der relevanten Informationen zu ermitteln und den Text zu extrahieren.

Abschließend wird eine Wörterbuchvariable mit dem Namen `data` zurückgegeben, die alle während des Scrapings gesammelten Informationen enthält, ergo eine wesentliche Voraussetzung für den folgenden Abschnitt.

 video_title = driver.find_elements(By.XPATH, '//*[@id="title"]/h1')[0].text

   owner = driver.find_elements(By.XPATH, '//*[@id="text"]/a')[0].text

   total_number_of_subscribers = \
       driver.find_elements(By.XPATH, "//div[@id='upload-info']//yt-formatted-string[@id='owner-sub-count']")[
           0].text

   video_description = driver.find_elements(By.XPATH,                                  '//*[@id="description-inline-expander"]/yt-attributed-string/span/span')
   result = []
   for i in video_description:
       result.append(i.text)
   description = ''.join(result)

   publish_date = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[2].text
   total_views = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[0].text

   number_of_likes = driver.find_elements(By.XPATH,                                   '//*[@id="top-level-buttons-computed"]/segmented-like-dislike-button-view-model/yt-smartimation/div/div/like-button-view-model/toggle-button-view-model/button-view-model/button/div')[
       1].text

   comment_names = driver.find_elements(By.XPATH, '//*[@id="author-text"]/span')
   comment_content = driver.find_elements(By.XPATH, '//*[@id="content-text"]/span')
   comment_library = []

   for each in range(len(comment_names)):
       name = comment_names[each].text
       content = comment_content[each].text
       indie_comment = {
           'name': name,
           'comment': content
       }
       comment_library.append(indie_comment)

   data = {
       'owner': owner,
       'subscribers': total_number_of_subscribers,
       'video_title': video_title,
       'description': description,
       'date': publish_date,
       'views': total_views,
       'likes': number_of_likes,
       'comments': comment_library
   }

   return data

except Exception as err:
   print(f"Error: {err}")

Schritt 4: Schreiben der gesammelten Daten in eine JSON-Datei

def organize_write_data(data:dict):
    output = json.dumps(data, indent=2, ensure_ascii=False).encode("ascii", "ignore").decode("utf-8")
    try:
        with open("output.json", 'w', encoding='utf-8') as file:
            file.write(output)
    except Exception as err:
        print(f"Error encountered: {err}")

Die Funktion `organize_write_data()` nimmt die zurückgegebenen `data` als Eingabe und organisiert sie in eine formatierte JSON-Struktur. Anschließend schreibt sie diese organisierten Daten in eine Ausgabedatei namens "output.json", wobei sie mögliche Fehler während des Schreibvorgangs behandelt.

Vollständiger Code

So, hier ist der vollständige Code unseres Scraping-Programms:

from selenium.webdriver.chrome.options import Options
from seleniumwire import webdriver as wiredriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
import json
import time

# Geben Sie die Adresse des Proxyservers mit Benutzernamen und Passwort an
proxy_address = ""
proxy_username = ""
proxy_password = ""

# Chrome-Optionen mit Proxy und Authentifizierung einrichten
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_address}')
chrome_options.add_argument(f'--proxy-auth={proxy_username}:{proxy_password}')

# Erstellen Sie eine WebDriver-Instanz mit selenium-wire
driver = wiredriver.Chrome(options=chrome_options)

youtube_url_to_scrape = ""

# Führen Sie Ihre Selenium-Automatisierung mit den erweiterten Möglichkeiten von selenium-wire durch
driver.get(youtube_url_to_scrape)


def extract_information() -> dict:
   try:
       element = WebDriverWait(driver, 15).until(
           EC.presence_of_element_located((By.XPATH, '//*[@id="expand"]'))
       )
       element.click()

       time.sleep(10)
       actions = ActionChains(driver)
       actions.send_keys(Keys.END).perform()
       time.sleep(10)
       actions.send_keys(Keys.END).perform()
       time.sleep(10)

       video_title = driver.find_elements(By.XPATH, '//*[@id="title"]/h1')[0].text

       owner = driver.find_elements(By.XPATH, '//*[@id="text"]/a')[0].text
       total_number_of_subscribers = \
           driver.find_elements(By.XPATH, "//div[@id='upload-info']//yt-formatted-string[@id='owner-sub-count']")[
               0].text

       video_description = driver.find_elements(By.XPATH,
                                                '//*[@id="description-inline-expander"]/yt-attributed-string/span/span')
       result = []
       for i in video_description:
           result.append(i.text)
       description = ''.join(result)

       publish_date = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[2].text
       total_views = driver.find_elements(By.XPATH, '//*[@id="info"]/span')[0].text

       number_of_likes = driver.find_elements(By.XPATH,
                                              '//*[@id="top-level-buttons-computed"]/segmented-like-dislike-button-view-model/yt-smartimation/div/div/like-button-view-model/toggle-button-view-model/button-view-model/button/div')[
           1].text

       comment_names = driver.find_elements(By.XPATH, '//*[@id="author-text"]/span')
       comment_content = driver.find_elements(By.XPATH,
                                              '//*[@id="content-text"]/span')
       comment_library = []

       for each in range(len(comment_names)):
           name = comment_names[each].text
           content = comment_content[each].text
           indie_comment = {
               'name': name,
               'comment': content
           }
           comment_library.append(indie_comment)

       data = {
           'owner': owner,
           'subscribers': total_number_of_subscribers,
           'video_title': video_title,
           'description': description,
           'date': publish_date,
           'views': total_views,
           'likes': number_of_likes,
           'comments': comment_library
       }

       return data

   except Exception as err:
       print(f"Error: {err}")


# Daten in JSON aufzeichnen
def organize_write_data(data: dict):
   output = json.dumps(data, indent=2, ensure_ascii=False).encode("ascii", "ignore").decode("utf-8")
   try:
       with open("output.json", 'w', encoding='utf-8') as file:
           file.write(output)
   except Exception as err:
       print(f"Error encountered: {err}")


organize_write_data(extract_information())
driver.quit()

Ergebnisse

Die Ausgabe sieht wie folgt aus:

Screenshot_1.png

Die sichere Nutzung des Informationsreichtums von YouTube ist von großem Vorteil, wenn gut ausgearbeitete Skripte eingesetzt werden, die Proxys verwenden, um die Einhaltung der Richtlinien und Vorschriften der Plattform zu gewährleisten. Der oben beschriebene Ansatz erleichtert eine verantwortungsvolle Datenextraktion und mindert das Risiko möglicher Einschränkungen durch die Plattform.

Bemerkungen:

0 Bemerkungen