Skip to content

Instantly share code, notes, and snippets.

@tjluoma
Last active January 3, 2023 09:00
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tjluoma/fdbc63ceb78a2aecd3d638fd18b6ec6e to your computer and use it in GitHub Desktop.
Save tjluoma/fdbc63ceb78a2aecd3d638fd18b6ec6e to your computer and use it in GitHub Desktop.
Did you know YouTube has RSS feeds? No? Probably because YouTube makes them nearly impossible to find. But here's an easy way to get the RSS feed for any YouTube user. Inspired by <https://eggfreckles.net/notes/youtube-rss/>
#!/usr/bin/env zsh -f
# Purpose: get the RSS feed for a YouTube page
# Inspired By: https://eggfreckles.net/notes/youtube-rss/
# Gist: https://gist.github.com/tjluoma/fdbc63ceb78a2aecd3d638fd18b6ec6e
#
# From: Timothy J. Luoma
# Mail: luomat at gmail dot com
# Date: 2020-01-17; updated 2021-01-10
# 2021-01-10 YouTube currently has both 'rssUrl' and
# link rel="alternate" type="application/rss+xml" title="RSS" href="…"
# which I do not believe where there a year ago when I first wrote this
# I am looking for the latter, and if I don't find it, I fallback to the
# former. If neither are found, an error is reported to the user.
#
# 2021-01-10 (Update 2): The previous comment only applies if you are looking
# at a channel page, i.e. "https://www.youtube.com/512pixels" but NOT if you
# are looking an an individual video such as 'https://www.youtube.com/watch?v=gQgSdwkvaDg'
#
# Version 2021-01-10.2 -- This script _should_ now work on either of those kinds of pages
NAME="$0:t:r"
if [[ -e "$HOME/.path" ]]
then
source "$HOME/.path"
else
PATH="/usr/local/scripts:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin"
fi
COUNT='0'
for URL in "$@"
do
LINK_REL=$(curl -sfLS "${URL}" \
| tr '<|>|,|\r' '\n' \
| awk -F'"' '/application\/rss\+xml/{print $8}')
if [[ "$LINK_REL" == "" ]]
then
## Do Not Indent
CHANNEL_ID=$(curl -sfLS "$URL" \
| sed -e 's#<#\
<#g' \
-e 's#>#>\
#g' \
| awk -F'"' '/meta itemprop="channelId"/{print $4}')
## END - Do Not Indent
if [[ "$CHANNEL_ID" == "" ]]
then
echo "$NAME: '\$CHANNEL_ID' and '\$LINK_REL' are both empty for '${URL}'." >>/dev/stderr
((COUNT++))
continue
else
FEED="https://www.youtube.com/feeds/videos.xml?channel_id=$CHANNEL_ID"
fi
else
FEED="$LINK_REL"
fi
echo "$FEED"
# copy URL to clipboard
echo -n "$FEED" | pbcopy
done
if [[ "$COUNT" == "0" ]]
then
# echo "$NAME: No errors"
exit 0
elif [[ "$COUNT" == "1" ]]
then
echo "$NAME: One error"
else
echo "$NAME: $COUNT errors"
fi
exit $COUNT
#EOF
@tjluoma
Copy link
Author

tjluoma commented Jan 19, 2020

Installation

  1. Download file as youtube-rss.sh.
  2. Save it somewhere like /usr/local/bin/youtube-rss.sh
  3. Run chmod 755 /usr/local/bin/youtube-rss.sh

Usage:

Just use youtube-rss.sh followed by one or more YouTube URLs, and the script will give you the corresponding RSS feed URLs.

For example:

youtube-rss.sh 'https://www.youtube.com/watch?v=3oeM_x11mog'

will

https://www.youtube.com/feeds/videos.xml?channel_id=UCZzXBTOSdtmOz9_VMYffr4g

(That's for Stephen Hackett‘s YouTube channel 512 Pixels.)

The RSS feed URL will also be copied to the clipboard/pasteboard. (If you ask it for multiple URLs, the last one will be on the clipboard.)

Thanks

Thanks to Thomas Brand for the YouTube RSS | Egg Freckles post which led me to write this.

@charsi
Copy link

charsi commented Nov 3, 2020

The updated eggfreckles link is https://eggfreckles.net/notes/youtube-rss/
Old one gives a 404 now.

@fredrikhr
Copy link

I exchanged line 21 to

CHANNEL_ID=$(curl -sfLS "$i" | grep -Eo '\"externalId\"\s*\:\s*\"([^\"]*)\"' | sed -E 's/\"externalId\"\s*\:\s*\"(.*?)\"/\1/g')

basically searching for externalId which seems to work better... ref: https://gist.github.com/arieljannai/24f71e84457d41d4ea5b34054d337346

@tjluoma
Copy link
Author

tjluoma commented Jan 10, 2021

Thanks! I checked again and YouTube seems to have made the RSS feeds easier to find (for now?) so I updated the script to look for the two most-common places it now appears.

BAH! No, I'm an idiot. My new script only works if you are already on the homepage for a channel, not the page of an individual video.

@tjluoma
Copy link
Author

tjluoma commented Jan 10, 2021

basically searching for externalId which seems to work better... ref:

I'm not finding externalId at all in URLs of YouTube videos. I do find them on the home pages of YouTube channels, but that's not what I wanted. My idea was to go from "I like this video, I want to find the RSS feed for this channel" not "I have a channel, show me the feed dor it.

@tjluoma
Copy link
Author

tjluoma commented Jan 10, 2021

Ok, as of 2021-01-10 around 5:55 pm US/Eastern, it should be working again, and should work better than before because you can use it both on homepages such as https://www.youtube.com/512pixels as well as individual videos such as https://www.youtube.com/watch?v=3oeM_x11mog

@DanSalib
Copy link

Hey, thanks for sharing.
I've tested with a few channels and noticed that not all the videos from youtube are available in the RSS feed.
Has anyone else also encountered this and know why that is the case?

@obsti8383
Copy link

obsti8383 commented Jan 22, 2022

If you just want to extract the URL with an Javascript Bookmarklet, just copy the following snippet in a bookmark link:

javascript:(()=>{alert(ytInitialData.metadata.channelMetadataRenderer.rssUrl);})();

Thanks @tjluoma for the hint in your comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment