Falls Sie Werbung auf Youtube schalten wollen, dann suchen Sie in der Regel nach anderen relevanten Kanälen, um Ihre Werbung dort auszuspielen.
Dieser Artikel zeigt Ihnen wie Sie anhand von ausgewählten Suchbegriffen und einem Python-Skript schnell relevante Kanäle finden können.
TL/DR: Den Link zum Notebook finden Sie am Ende des Artikels.
Benötigte Bibliotheken
Zu Beginn installieren wir ausgewählte Bibliotheken, um z.B. auf die Youtube API zuzugreifen und später die Ergebnisse in einer Excel-Datei zu speichern.
!pip install pandas openpyxl
!pip install google-api-python-client
!pip install python-slugify
Im Anschluss importieren wir diese:
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
import json
import time
import pandas as pd
from datetime import datetime
from slugify import slugify
Um auf die Schnittstelle zuzugreifen, benötigen Sie einen Google-API-Key. Ein API-Key ist eine eizigartige Identifizierungsnummer, welche dann zum Einsatz kommt wenn wenn es zum Austausch zwischen zwei Programmen kommt. Dieser Austausch erfolgt über sogenannte Programmierschnittstellen, oder auch APIs genannt, für welche dann eben jener API-Key benötigt wird, damit der API-Server Zugriff auf die angeforderten Daten gewährt.
Wir greifen hier auf die Youtube API zu, daher müssen Sie sich vorher einen entsprechenden Schlüssel bei Youtube einrichten.
Dies können Sie hier tun:
https://developers.google.com/youtube/registering_an_application?hl=en
Sobald Sie den Key haben, müssen Sie diesen entweder in einer .env
Datei speichern oder direkt im Skript hinterlegen.
# Load variables from .env file
load_dotenv('.env')
# Use variables
api_key = os.getenv('YOUTUBE_API_KEY')
# Alternative: Set it directly
# https://console.cloud.google.com/apis/credentials
# api_key = "xxx"
Wichtig: Die Youtube-API erlaubt je Key ca. 1.000 Zugriffe pro Tag. Größere Recherchen müssen daher gut geplant werden.
Relevante Funktionen
Da nun alles für die Funktion erforderliche installiert wurde kommen wir zum interessanten Teil.
Mit Hilfe der folgenden Funktion können wir Youtube durchsuchen und entweder relevante Kanäle oder Videos als Ergebnis zurückerhalten:
# Searches channels for a query
def search_youtube(query, type = "channel"):
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=api_key)
next_page_token = None
all_results = []
i = 0
while True:
i = i + 1
print(f"Query: {query} | Type {type} | Page: {i}")
request = youtube.search().list(
part="snippet",
type=type, # channel of video
q = query, # Set below
regionCode = regionCode, # Set below
maxResults=50,
order="date",
pageToken=next_page_token
)
response = request.execute()
all_results += response['items']
time.sleep(2) # Avoid rate limits
if 'nextPageToken' in response:
next_page_token = response['nextPageToken']
else:
break
return all_results
Hier ein Beispiel:
response = search_youtube("amazon vendor", "video", 1)
print(json.dumps(response[:2], indent=2)) # First three elements
Als Ergebnis liefert die Youtube API folgendes zurück (Auszug):
[
{
"kind": "youtube#searchResult",
"etag": "1gd_KoispJGxmVgkmnYZ6X4L0X8",
"id": {
"kind": "youtube#channel",
"channelId": "UCB757sBODw3eNPUl8jbdRZQ"
},
"snippet": {
"publishedAt": "2023-11-04T11:20:18Z",
"channelId": "UCB757sBODw3eNPUl8jbdRZQ",
"title": "Amazon Amazing Deals",
"description": "Welcome to Amazon Amazing Dealsamazon online products, amazon sell products online, how to sell digital products online on ...",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/naoFnpSQ7xsrImq_N1sit9okp0GZur3MGk_lPxL4wGbVg8kzunMRY3L3Aw-zDThccgPyPEO7Iw=s88-c-k-c0xffffffff-no-rj-mo"
},
"medium": {
"url": "https://yt3.ggpht.com/naoFnpSQ7xsrImq_N1sit9okp0GZur3MGk_lPxL4wGbVg8kzunMRY3L3Aw-zDThccgPyPEO7Iw=s240-c-k-c0xffffffff-no-rj-mo"
},
"high": {
"url": "https://yt3.ggpht.com/naoFnpSQ7xsrImq_N1sit9okp0GZur3MGk_lPxL4wGbVg8kzunMRY3L3Aw-zDThccgPyPEO7Iw=s800-c-k-c0xffffffff-no-rj-mo"
}
},
"channelTitle": "Amazon Amazing Deals",
"liveBroadcastContent": "none",
"publishTime": "2023-11-04T11:20:18Z"
}
}
...
Mit einer zweiten Funktion erhalten wir für einen bestimmten Kanal alle relanvten Informationen des Kanals.
# Returns channel details for a channelId
def get_channel_details(channel_id):
youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=api_key)
request = youtube.channels().list(
part=["snippet", "statistics"],
id = channel_id
)
response = request.execute()
return response['items']
Die Funktion benötigt die eindeutige Kanal-ID, z.B. UCxkIzPnPzWLz4IeuxIROflg
:
Beispiel:
response = get_channel_details('UCxkIzPnPzWLz4IeuxIROflg')
print(json.dumps(response, indent=2))
Ergebnis:
[
{
"kind": "youtube#channel",
"etag": "tF64tb7FLNTj7rU_3khtRJfqyn4",
"id": "UCxkIzPnPzWLz4IeuxIROflg",
"snippet": {
"title": "Travis Marziani",
"description": "This channel will teach you how to leverage Amazon FBA, Shopify, Adwords, Facebook ads and other secret internet marketing strategies to create a business you love, create freedom and enjoy the journey. \n\nI have done well over 7 figures of sales on and off Amazon, and want to share what I wish I would have known when I first started, including how to create a passion product. \n\nI was depressed and stuck in the corporate world , when I quit that to start an online dance clothing business with my mom. After years of growing the revenue but struggling to make enough profit to support my self I had to move back in with my parents. It was at this point I realized I want to create a business I was passionate about, and I took all the lessons learned and created my first passion product which went on to make me six figures passive income, and more importantly I loved my business, my life and I started enjoying the journey.\n\nFollow Me on Instagram: @travismarziani for daily tips",
"customUrl": "@travismarziani",
"publishedAt": "2015-07-09T18:38:41Z",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/ytc/APkrFKbRNTzyFG7dJrtniw0I_PpU8r6qAiFh5c7BNgKHTQ=s88-c-k-c0x00ffffff-no-rj",
"width": 88,
"height": 88
},
"medium": {
"url": "https://yt3.ggpht.com/ytc/APkrFKbRNTzyFG7dJrtniw0I_PpU8r6qAiFh5c7BNgKHTQ=s240-c-k-c0x00ffffff-no-rj",
"width": 240,
"height": 240
},
"high": {
"url": "https://yt3.ggpht.com/ytc/APkrFKbRNTzyFG7dJrtniw0I_PpU8r6qAiFh5c7BNgKHTQ=s800-c-k-c0x00ffffff-no-rj",
"width": 800,
"height": 800
}
},
"localized": {
"title": "Travis Marziani",
"description": "This channel will teach you how to leverage Amazon FBA, Shopify, Adwords, Facebook ads and other secret internet marketing strategies to create a business you love, create freedom and enjoy the journey. \n\nI have done well over 7 figures of sales on and off Amazon, and want to share what I wish I would have known when I first started, including how to create a passion product. \n\nI was depressed and stuck in the corporate world , when I quit that to start an online dance clothing business with my mom. After years of growing the revenue but struggling to make enough profit to support my self I had to move back in with my parents. It was at this point I realized I want to create a business I was passionate about, and I took all the lessons learned and created my first passion product which went on to make me six figures passive income, and more importantly I loved my business, my life and I started enjoying the journey.\n\nFollow Me on Instagram: @travismarziani for daily tips"
},
"country": "US"
},
"statistics": {
"viewCount": "21222438",
"subscriberCount": "330000",
"hiddenSubscriberCount": false,
"videoCount": "552"
}
}
]
Start der Recherche
Mit Hilfe dieser beiden Funktionen können wir das Skript nun starten.
Wir definieren zu Beginn noch drei Parameter:
- Den sog.
regionCode
, mit Hilfe dessen wir innerhalb einer bestimmten Region suchen können - Unsere Suchwörter (
queries
), die wir zur Suche nutzen - Die Anzahl der Seiten (
max_pages
), die wir je Suche zurückerhalten. Pro Seite liefert die Youtube-API max. 50 Ergebnisse.
regionCode = "US"
queries = ["amazon marketing", "amazon fba"] # Add queries here!
max_pages = 2 # Defines the number of results per page (50 results per page)
Im Anschluss starten wir dann den Hauptteil des Skriptes:
# Create empty array
data = []
channel_ids = []
for query in queries:
channels = search_youtube(query, "channel")
videos = search_youtube(query, "video")
channel_ids_channels = [item['snippet']['channelId'] for item in channels]
channel_ids_videos = [item['snippet']['channelId'] for item in videos]
channel_ids_temp = list(set(channel_ids_channels + channel_ids_videos))
print(f"Query: {query}: Found {len(channel_ids_channels)} channels and {len(channel_ids_videos)} videos")
channel_ids.append(channel_ids_temp)
# Flatten list of lists
channel_ids_flat = [item for sublist in channel_ids for item in sublist]
# Remove duplicates
channel_ids_flat = list(set(channel_ids_flat))
print(f"Found {len(channel_ids_flat)} unique channel_ids")
# Search for channels for this query
for channel_id in channel_ids_flat:
channel_details = get_channel_details(channel_id)
Zusätzlich zu den Kanälen allein werden auch noch weitere Informationen über die Kanäle abgefragt, wie z.B. die Anzahl der Abbonenten. Auf Basis dessen lassen sich irrelevante Kanäle mit einem zu geringen Bekanntheitsgrad herausfiltern, sodass nur relevante Kanäle am Ende gelistet werden.
for detail in channel_details:
data.append({
'id': detail['id'],
'description': detail['snippet'].get('description', ''),
'customUrl': detail['snippet'].get('customUrl', ''),
'link': 'https://www.youtube.com/c/' + detail['snippet'].get('customUrl', ''),
'country': detail['snippet'].get('country', ''),
'viewCount': detail['statistics'].get('viewCount', ''),
'subscriberCount': detail['statistics'].get('subscriberCount', ''),
'videoCount': detail['statistics'].get('videoCount', '')
})
# Convert the list of dicts to a DataFrame
df = pd.DataFrame(data)
# Make columns integers
df = df.astype({"viewCount":"int","subscriberCount":"int","videoCount":"int"})
print(f"Before duplicates: {len(df)}")
# Remove duplicates
df = df.drop_duplicates(subset='id', keep="first")
print(f"Before filter: {len(df)}")
# Filter only channels which have more than 50 subscribers
df = df[df['subscriberCount'] > 50]
# Filter only channels which have more than 5 videos
df = df[df['videoCount'] > 5]
# Sort df by subscribers
df = df.sort_values('subscriberCount', ascending=False)
print(f"Final result: {len(df)}")
# Get the current date and time and format it
current_datetime = datetime.now().strftime("%Y-%m-%d-%H-%M")
query_slug = slugify(query)
filename = f"{current_datetime}-{regionCode}-channel_details.xlsx"
# Save the DataFrame to an Excel file with the prefixed filename
df.to_excel(filename, index=False)
df
Das Programm durchläuft für jeden Suchbegriff die folgenden Schritte:
- Relevante Kanäle finden
- Relevante Videos finden
- Zu den Kanälen und Videos die Kanal-IDs finden und Duplikate entfernen
- Zu jeder Kanal-ID die Daten abfragen
- Kanäle herausfiltern, die weniger als eine bestimmte Anzahl von Videos und Abonnenten haben
- Kanäle herausfiltern, die ein bestimmtes Suchwort in der Beschreibung nicht enthalten
- Alles in einer Excel-Datei abspeichern
Ausgabe der Daten
Um die durchaus umfangreiche Liste der YouTube Kanäle übersichtlich zu gestalten lässt sich diese Liste in eine Excel-Datei umwandeln, sodass alles strukturiert und leicht einlesbar vorliegt.
Es empfiehlt sich jedoch die Liste nochmals manuell durchzugehen, da sich doch hin und wieder einige Blindgänger finden lassen.
Das gesamte Google Colab Notebook finden Sie hier.
Um dieses Skript zu verwenden, müssen Sie vorher Ihren API-Key verwenden.
Viel Erfolg!
Weitere Artikel, die Ihnen erklären, wie Sie unter anderem mit Pandas arbeiten: