Youtube Video Details Scraper avatar

Youtube Video Details Scraper

Pricing

from $5.99 / 1,000 results

Go to Apify Store
Youtube Video Details Scraper

Youtube Video Details Scraper

YouTube Video Details Scraper extracts video titles, descriptions, tags, view counts, likes, comments, upload dates, channel information, and more from YouTube videos. Ideal for SEO analysis, competitor research, content tracking, market research, and data-driven decision-making.

Pricing

from $5.99 / 1,000 results

Rating

0.0

(0)

Developer

ScrapeVanta

ScrapeVanta

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

YouTube Video Details Scraper — Metadata, Engagement Metrics and Searchable Transcripts

Pull full details for any YouTube video, or point it at a channel or playlist and let it expand that into videos for you. Every record carries the real numbers, derived engagement metrics, creator chapters, and a transcript you can actually search — with timestamps and links that jump straight to the moment.

No API key. No quota.


What it does

Videos, channels and playlists all work, in every URL form people actually paste:

You pasteIt understands
youtube.com/watch?v=…, youtu.be/…, /shorts/…, /live/…, /embed/…A single video
A bare 11-character IDA single video
youtube.com/@handle, or just @handleThe channel's recent uploads
youtube.com/channel/UC…, or a bare UC… IDThe channel's recent uploads
youtube.com/playlist?list=PL…, or a bare playlist IDThe playlist's videos

Channels and playlists are expanded through YouTube's own public feed — a documented endpoint that needs no key and no quota. Handles are resolved to a channel ID automatically.

Anything unrecognised is reported back to you by name rather than silently dropped, so a run never quietly comes up short.

2. Search inside the transcript

Give it search terms and every match comes back with a timestamp, the surrounding sentence, and a link that opens the video at that second.

The important detail: phrases are matched across caption boundaries. Captions break wherever the line ran out, so "machine learning" is routinely split into …about machine / learning and…. Matching fragment by fragment misses those. The transcript is joined first and matches are traced back to the fragment that contains them, which is how each hit still gets an accurate timestamp.

Alongside search you get the transcript as readable plain text (caption artefacts like [Music] and >> SPEAKER: removed), a word count, the speaking rate in words per minute, transcript coverage, and the most frequent meaningful words with their share of the transcript.

3. Engagement metrics, honestly derived

FieldWhat it is
engagementRatePercent(likes + comments) ÷ views, as a percentage
likeRatePercentlikes ÷ views
commentRatePercentcomments ÷ views
viewsPerDayviews ÷ days since publication
videoAgeDaysdays since publication

Sort by any of them, or filter on views, duration, publish date, keyword, or "must have a transcript".

Where the numbers come from, since it matters: the view count and like count are exact figures read from the page. The comment count is only ever published rounded ("2.4M") on videos of any size, so it is named commentCountApprox and the original label is kept in commentCountText — a rounded number is not presented as a precise one. Engagement rate is a conventional proxy computed from public counts; views are not unique viewers.

4. Chapters, tags and format

Creator chapter markers are read out of the description and returned with start time, end time, duration and a deep link. Timestamps that aren't chapters — links to other videos, track listings — are rejected by requiring them to ascend and to fall inside the runtime.

isShortFormat comes from the canonical URL, which is the only reliable signal. (Requesting /shorts/<id> directly proves nothing: it redirects for every video, Short or not.)

maxResolution and maxFps are read from the actual stream list, so a 4K video reports 4K.


Input

FieldTypeDefaultDescription
videoUrlsarrayVideos, in any URL form or as bare IDs
channelUrlsarrayChannel links, @handles or UC… IDs
playlistUrlsarrayPlaylist links or IDs
maxVideosPerSourceinteger10Videos to take from each channel/playlist
includeTranscriptbooleantrueFetch and analyse captions
transcriptLanguagesarray["en"]Preferred languages, in order
transcriptSearchTermsarrayTerms to locate, with timestamps
includeTranscriptSnippetsbooleanfalseInclude every timed caption segment
keywordCountinteger15Keywords to report per video
includeChaptersbooleantrueExtract chapter markers
includeDescriptionbooleantrueKeep the full description
minViewCountintegerDrop videos below this
minDurationSecondsintegerDrop shorter videos (61 excludes Shorts)
maxDurationSecondsintegerDrop longer videos
publishedAfterstringYYYY-MM-DD or ISO timestamp
filterKeywordsarrayTitle/description must contain one
requireTranscriptbooleanfalseOnly keep videos with captions
sortBystringdiscovery orderViews, likes, date, engagement, …
sortDescendingbooleantrueHighest first
concurrentRequestsinteger5Videos fetched at once
emitRunSummarybooleantrueAppend the aggregate record
proxyConfigobjectApify Proxy onProxy settings; effectively required on the platform

At least one of videoUrls, channelUrls or playlistUrls is required.

Example input

{
"channelUrls": ["@RickAstleyYT"],
"maxVideosPerSource": 10,
"includeTranscript": true,
"transcriptSearchTerms": ["never gonna give you up"],
"minViewCount": 10000,
"sortBy": "engagementRatePercent",
"sortDescending": true
}

Output

One video record per video, then an optional summary.

Video record fields

Identity

FieldDescription
videoId, videoUrl, canonicalUrlThe video's ID, a watch link, and YouTube's own canonical link
videoTitle, descriptionTitle and full description (description omitted if you turn it off)
channelName, channelId, channelHandle, channelUrlWho published it
subscriberCountText, subscriberCountApproxChannel size as shown, and parsed to a number
discoveredViaWhether this video came from a direct link, a channel feed or a playlist feed
scrapedAtWhen this row was taken

Timing and format

FieldDescription
publishedAt, uploadedAtPublish and upload timestamps (they differ for scheduled videos)
durationSeconds, durationTextRuntime in seconds and as M:SS / H:MM:SS
isShortFormatWhether it's a Short, from the canonical URL
isLiveContent, isPrivate, isUnlisted, isFamilySafe, allowRatingsStatus flags as YouTube reports them
category, audioLanguageCategory, and the declared audio language when the video sets one
maxResolution, maxWidth, maxHeight, maxQualityLabel, maxFpsHighest quality actually offered
thumbnailUrlLargest available thumbnail

Counts and engagement

FieldDescription
viewCount, likeCountExact figures
commentCountApprox, commentCountTextRounded comment count, and YouTube's original label
ratingAverage, ratingCountStar rating, when the video arrived via a feed that carried it
engagementRatePercent, likeRatePercent, commentRatePercentRatios against views
viewsPerDay, videoAgeDaysReach per day, and age

Content

FieldDescription
tags, hashtagsCreator tags, and hashtags found in the title and description
chapters, chapterCountChapter markers with start, end, duration and title
hasCaptions, captionLanguagesWhether captions exist, and in which languages

Transcript (when includeTranscript is on)

FieldDescription
transcriptAvailable, transcriptError, transcriptLanguageWhether a transcript was retrieved, and why not if it wasn't
transcriptTextCleaned, readable plain text
transcriptWordCount, transcriptCharacterCountLength
speakingRateWpm, readingTimeMinutes, transcriptCoveragePercentPace, reading time, and how much of the runtime the captions span
topKeywordsMost frequent meaningful words with counts and shares
searchHits, searchHitTotalMatches for your search terms, with timestamps and deep links
transcriptSnippetsEvery timed caption segment (only when you ask for it)

Failure

FieldDescription
fetchFailed, fetchErrorWhether the video could be read, and the reason

Example video record

{
"recordType": "video",
"videoId": "dQw4w9WgXcQ",
"videoUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"videoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
"channelName": "Rick Astley",
"channelId": "UCuAXFkgsw1L7xaCfnd5JJOw",
"channelHandle": "@RickAstleyYT",
"subscriberCountText": "4.53M subscribers",
"subscriberCountApprox": 4530000,
"publishedAt": "2009-10-24T23:57:33-07:00",
"durationSeconds": 213,
"durationText": "3:33",
"viewCount": 1803235213,
"likeCount": 19332287,
"commentCountApprox": 2400000,
"commentCountText": "2.4M",
"engagementRatePercent": 1.2052,
"likeRatePercent": 1.0721,
"viewsPerDay": 293512,
"videoAgeDays": 6136.0,
"category": "Music",
"isShortFormat": false,
"isLiveContent": false,
"isFamilySafe": true,
"maxResolution": "3840x2160",
"maxFps": 25,
"tags": ["rick astley", "Never Gonna Give You Up", "nggyu"],
"hashtags": [],
"hasCaptions": true,
"captionLanguages": ["en", "de-DE", "ja"],
"transcriptLanguage": "en",
"transcriptWordCount": 366,
"speakingRateWpm": 103.1,
"transcriptCoveragePercent": 99.2,
"topKeywords": [{ "keyword": "gonna", "occurrences": 24, "sharePercent": 14.55 }],
"searchHits": [
{
"term": "never gonna give you up",
"matchCount": 6,
"occurrences": [
{
"startSeconds": 43.0,
"startTime": "0:43",
"context": "…we're no strangers to love never gonna give you up never gonna let you down…",
"linkUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=43s"
}
]
}
],
"chapters": [],
"chapterCount": 0,
"discoveredVia": "direct link",
"fetchFailed": false,
"scrapedAt": "2026-08-12T09:00:00+00:00"
}

A video that cannot be read still produces a row with fetchFailed: true and the reason in fetchError. Where possible the title and channel are filled in from YouTube's public oEmbed endpoint, so a blocked page still tells you which video failed.

Summary record

{
"recordType": "summary",
"videosAttempted": 10,
"videosSucceeded": 10,
"videosFailed": 0,
"failedVideoIds": [],
"sourcesRequested": ["@RickAstleyYT"],
"inputsRejected": [],
"totalLikes": 21400418,
"transcriptsRetrieved": 8,
"shortsCount": 3,
"totalViews": 2104882133,
"averageViews": 210488213,
"medianViews": 270575.0,
"averageEngagementRatePercent": 2.41,
"averageDurationSeconds": 128.4,
"totalTranscriptWords": 4820,
"channelBreakdown": { "Rick Astley": 10 },
"categoryBreakdown": { "Music": 8, "Entertainment": 2 },
"topTags": [{ "tag": "rick astley", "videoCount": 6 }],
"mostViewedVideoId": "dQw4w9WgXcQ",
"mostViewedVideoTitle": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
"mostEngagingVideoId": "JjI4o2w6D5A",
"finishedAt": "2026-08-12T09:00:22+00:00"
}

Common use cases

  • Content research — pull a competitor's recent uploads and sort by engagement rate to see what actually lands, not just what got views.
  • Finding the moment — search a long interview or conference talk for a topic and get links straight to every mention.
  • Repurposing — the cleaned transcript, chapters and keyword profile are the raw material for blog posts, show notes and clips.
  • SEO and tag researchtopTags across a channel's catalogue shows what they consistently tag for.
  • Monitoring — run on a schedule against a channel and track viewsPerDay as videos age.
  • Dataset building — transcripts plus metadata for a set of videos, in one pass.

Notes and limits

  • The public feed is short. Channel and playlist expansion returns roughly the 15 most recent items and offers no paging, so maxVideosPerSource cannot exceed what the feed holds. To go deeper, supply video URLs directly. The run log says when the feed was the limiting factor.
  • Comment counts are rounded by YouTube, not by this Actor. Large videos publish "2.4M" and nothing more precise. commentCountApprox carries the parsed number, commentCountText the original label.
  • Transcripts depend on the video having captions. Many do not, and some creators disable them. transcriptAvailable and transcriptError say which case you hit, per video, instead of returning an empty string that looks like a silent video.
  • Run this with a proxy. Apify's shared outbound addresses are heavily used against YouTube, and a run without proxyConfig is answered with "Sign in to confirm you're not a bot" for most videos. Measured on the platform: with no proxy, 1 of 4 videos returned data; with Apify Proxy enabled, 5 of 5 returned data and transcripts. Either the default datacenter group or a residential group works; residential holds up better across long runs.
  • Videos that fail this way still produce a row. Titles, view counts, publish dates and the Shorts flag come from the public feed when a channel or playlist supplied them, so a challenged run degrades to less data rather than to none.
  • Auto-generated captions contain errors. Speaking rate, word counts and keyword frequencies inherit them. Treat them as good estimates, not transcription-grade output.
  • speakingRateWpm is words divided by video length, so long musical or silent passages pull it down. That is the honest figure for the video, not for the speech within it.
  • Age-restricted, private, members-only and region-locked videos cannot be read without signing in, and are reported as failures with the reason.
  • Legacy /c/Name and /user/Name channel URLs no longer resolve for many channels. Use the @handle or the /channel/UC… form.
  • View and like counts change constantly. scrapedAt records when each row was taken.
  • This Actor reads only public pages and public feeds. It does not sign in, and cannot reach anything that requires an account.

Local development

pip install -r requirements.txt
python -m tests.test_core # 172 checks, including live requests to YouTube
apify run