Skip to content

Instantly share code, notes, and snippets.

@noahbroyles
Created October 25, 2021 18:10
Show Gist options
  • Save noahbroyles/fad094f1a9a43794f243b8e3ae9b8e4c to your computer and use it in GitHub Desktop.
Save noahbroyles/fad094f1a9a43794f243b8e3ae9b8e4c to your computer and use it in GitHub Desktop.
Gets search suggestions from YouTube Music
# AUTHOR: Noah Broyles
# DESCRIPTION: Uses the YouTube Music search suggestions API to get search suggestions from a query. API key already provided, scraped cleanly right off
# youtube's own site. ;)
#
# Last Working: Oct 25, 2021
import re
import json
import requests
from addict import Dict
# This API does use some form of key, which is automatically borrowed from YouTube ;)
INNERTUBE_API_KEY = 'AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30'
# This is run when we are no longer getting results from the API
def refresh_api_key():
global INNERTUBE_API_KEY
print('Refreshing API key')
index_page = requests.get('https://music.youtube.com', headers={"user-agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0"})
html = index_page.content.decode()
# The exact length of the key as of 9/28/2021 is 39. 4 years ago (https://stackoverflow.com/questions/44614612) it was also 39.
# So it's safe to assume a length of 39.
INNERTUBE_API_KEY = re.findall(r'"INNERTUBE_API_KEY":\s*"(.{39})",', html)[0]
print(f"The new INNERTUBE_API_KEY is {INNERTUBE_API_KEY}")
# Returns a list of YouTubeMusic search suggestions from a query, q
def get_suggestions(q):
API_HEADERS = {
"origin": "https://music.youtube.com",
"referrer": "https://music.youtube.com/",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "same-origin",
"sec-fetch-site": "same-origin",
"x-youtube-client-name": "69",
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0,gzip(gfe)"
}
# I only choose to send them SOME of my data
REQUEST_BODY = json.dumps({
"input": q,
"context": {
"client": {
"hl": "en",
"gl": "US",
"deviceMake": "",
"deviceModel": "",
#"visitorData": "CgsyR2o3ZmRqUEdjMCi5xsyKBg%3D%3D",
"userAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0,gzip(gfe)",
"clientName": "WEB_REMIX",
"clientVersion": "1.20210922.00.00",
"osName": "X11",
"osVersion": "",
"originalUrl": "https://music.youtube.com/",
"platform": "DESKTOP",
"clientFormFactor": "UNKNOWN_FORM_FACTOR",
#"configInfo": {
# "appInstallData": "CLnGzIoGEJPVrQUQ_tatBRCzhP0SENi-rQU%3D"
#},
"browserName": "Firefox",
"browserVersion": "92.0",
#"screenWidthPoints": 1316,
#"screenHeightPoints": 605,
#"screenPixelDensity": 1,
#"screenDensityFloat": 1,
#"utcOffsetMinutes": -240,
"userInterfaceTheme": "USER_INTERFACE_THEME_DARK",
"timeZone": "America/New_York",
"musicAppInfo": {
"pwaInstallabilityStatus": "PWA_INSTALLABILITY_STATUS_UNKNOWN",
"webDisplayMode": "WEB_DISPLAY_MODE_BROWSER",
"musicActivityMasterSwitch": "MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE",
"musicLocationMasterSwitch": "MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE"
}
},
"user": {
"lockedSafetyMode": False
},
"request": {
"useSsl": True,
"internalExperimentFlags": [],
"consistencyTokenJars": []
}
}
})
# Make the request to the API
suggestion_data = Dict(requests.post(f'https://music.youtube.com/youtubei/v1/music/get_search_suggestions?key={INNERTUBE_API_KEY}', data=REQUEST_BODY, headers=API_HEADERS).json())
# Gather our suggestions
suggestions = [element.searchSuggestionRenderer.navigationEndpoint.searchEndpoint.query for element in suggestion_data.contents[0].searchSuggestionsSectionRenderer.contents]
# The suggestions list will be empty if the API key is not correct
if not suggestions:
# Something about the API key was wrong
refresh_api_key()
return get_suggestions(q)
else:
return suggestions
if __name__ == '__main__':
print(get_suggestions("yeah us"))
"""
['yeah usher', 'yeah usher clean', 'yeah usher lyrics', 'yeah usher remix', 'yeah usher clean radio edit', 'yeah usher instrumental', 'yeah usher slowed']
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment