YouTube Transcript Scraper
Pricing
from $5.00 / 1,000 successful video transcripts
YouTube Transcript Scraper
Collect public YouTube captions with real timestamps, language selection and optional text exports. Also validate and search supplied transcript records. No paid transcript API or Google API key required.
Pricing
from $5.00 / 1,000 successful video transcripts
Rating
0.0
(0)
Developer
Inus Grobler
Maintained by CommunityActor stats
1
Bookmarked
28
Total users
0
Monthly active users
7 days ago
Last modified
Categories
Security
Limited permissionsShare
Scrape public YouTube captions into clean, timestamped transcript segments for research, searchable archives and content analysis. Collect video IDs, source URLs, languages, caption text and timing, with video titles and channel details when enabled. No Google Data API key or paid transcript service is required.
Use cases
- Build searchable lecture, interview and podcast transcript collections.
- Match quotations and topics to their actual video timestamps.
- Prepare caption datasets for analysis, retrieval and accessibility workflows.
Key features
- Public video URLs, Shorts, embeds, live-video URLs and bare video IDs.
- Language preferences with an available-language fallback.
- A global caption-row limit and separate per-video character cap.
- Duplicate video URLs are fetched and delivered once per run.
- Optional combined text exports and video/channel metadata.
- Native Apify proxy support, bounded retries and spending-limit handling.
- Optional processing and literal search of transcripts you supply.
The Actor reads YouTube's public watch pages and first-party caption/player responses. It does not call an external transcript provider, another Actor or a model API, and does not invent transcripts for videos without captions.
Quick start
- Open Input and replace the example video with your YouTube URL or video ID.
- Set Maximum caption rows and optionally choose preferred languages.
- Start the Actor and export the default dataset as JSON, CSV or Excel.
The form has three main controls and a Proxy routing section. Leave Use residential proxy selected for the preview: YouTube blocked datacenter requests during cloud verification. Other advanced and compatibility settings remain available through JSON input.
Minimal cloud input:
{"videoUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],"maxResults": 10,"useResidentialProxy": true}
For long transcripts, set maxChars: 100000 in JSON or API input. Runs omitting maxChars retain the historical 1,000-character default. Enable fetchVideoMeta for titles and channel details.
Sample output
Each row contains one real caption cue. This shortened example shows the output shape; actual caption wording and timing depend on the selected source track.
{"record_type": "transcript_piece","video_id": "jNQXAC9IVRw","url": "https://www.youtube.com/watch?v=jNQXAC9IVRw","title": "Me at the zoo","status": "found","language": "en","piece_index": 1,"piece_count": 6,"piece_start": 0,"piece_dur": 2,"text": "All right, so here we are","dataInputSource": "web","sourceVerified": true,"transcript_truncated": false}
Important output fields
| Field | Meaning |
|---|---|
video_id, url | Native video ID and canonical YouTube source link. |
text, language | Caption text and the selected track's language. |
piece_start, piece_dur | Real caption start and duration in seconds; zero starts are preserved. |
piece_index, piece_count | Cue position and the number of pieces considered before the global row or spending cap. |
title, channel_id, channel_name | Source metadata when fetchVideoMeta is enabled. |
transcript_truncated | The per-video character budget cut transcript coverage. Global row and spending limits are reported separately in OUTPUT. |
dataInputSource, sourceVerified | web and true for live collection; supplied records retain provided and false. |
The per-run unique key is (video_id, language, piece_index). Repeated video URLs do not repeat caption rows or successful-video events.
Enable exportVideoText to also save a combined document under TRANSCRIPT-<video_id> in the run key-value store. It contains only delivered segments. OUTPUT contains totals, export references, source timings, skipped duplicate counts, stopping reasons and missing-video diagnostics. These diagnostics are kept outside the customer dataset. Signed caption URLs may expire; the canonical url remains the stable source link.
Limits, supported data and pagination
Only captions actually available on public YouTube videos are collected. Private, removed, restricted, unfinished live or uncaptioned videos may yield no transcript. YouTube may block an IP or require a new session. Captions can contain transcription errors.
maxResults limits caption rows across the whole run. It is a ceiling, not a promise that a video contains that many cues. Omit it in legacy API input to preserve the previous unlimited-row behavior. maxChars independently limits combined text per video; whichever limit is reached first applies. A stopped run can therefore contain only part of a transcript.
A YouTube caption document contains its cue list in one response, so caption collection has no page cursor. Multiple video URLs are processed as a bounded batch. Channel, playlist and search-result discovery are not supported; provide individual video links. Global row and charge limits stop further delivery, and active requests remain bounded by their timeouts.
The cloud preview uses Apify's supported residential proxy infrastructure. API clients should explicitly set useResidentialProxy: true when cloud/datacenter requests are blocked; omitting it preserves the historical false default. No external proxy subscription is needed.
Missing captions never become paid placeholder rows. If all videos are unavailable, the Actor fails clearly. A mixed run retains valid captions and reports failed videos in OUTPUT.
Pricing and useful cost controls
Live collection has three small charges, in USD:
| Charge | Price | When it applies |
|---|---|---|
| Successful video transcript | $0.005 per video ($5 per 1,000) | Once per unique video with at least one delivered caption segment |
| Dataset row | $0.00001 per row ($0.01 per 1,000) | Each delivered caption segment, or each delivered supplied record |
| Actor start | $0.00005 per run at 128 MB | Apify charges one start event per GB of allocated memory, with a minimum of one |
Total at the default memory = $0.00005 + ($0.005 × successful videos) + ($0.00001 × delivered rows). For one video, 10 caption rows cost $0.00515, 100 rows cost $0.00605, and 1,000 rows cost $0.01505. These are price calculations, not promises that a video contains that many captions. A dataset row is one timed caption segment, not a whole video transcript.
Native Apify proxy and runtime usage are included in these event prices for standard runs. Duplicate video URLs within a run are collected and charged once. Failed videos produce no successful-video or caption-row charge; the run-start fee still applies. Optional combined text exports add no event charge. Supplied-record processing uses only the dataset-row and run-start charges. The Store pricing panel shows the current rates.
Use one or a few URLs, maxResults and the Console maximum-cost setting to bound a collection. If the budget cannot cover the next successful-video event, the Actor stops before requesting that video. Native proxy and runtime resource use varies with video length and blocking; small-run measurements do not establish a bulk cost guarantee.
Process transcripts you already have
Advanced providedRecords or an accessible providedDatasetId selects supplied-data processing instead of live collection. Use one supplied source at a time and clear records to [] when selecting a dataset. providedRecordLimit caps scanned supplied records. Optional analysisQuery performs a literal phrase search over delivered supplied records.
PROVIDED_DATA_SUMMARY reports validation and delivery counts; EVIDENCE_ANALYSIS contains the supplied-record timestamp index and phrase matches. Supplied records are not independently verified and cannot establish live website collection. Empty records with no dataset leave live scraping enabled.
Python API example
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("NyLjBIvZHHt6Ph5Gi").call(run_input={"videoUrls": ["https://www.youtube.com/watch?v=jNQXAC9IVRw"],"maxResults": 10,"preferredLanguages": ["en"],"maxChars": 100000,"fetchVideoMeta": True,"useResidentialProxy": True,})if run is None:raise RuntimeError("Actor run did not complete")dataset_id = run["defaultDatasetId"] if isinstance(run, dict) else run.default_dataset_idfor item in client.dataset(dataset_id).iterate_items():print(item["video_id"], item.get("piece_start"), item["text"])
Troubleshooting and FAQ
Why are there fewer rows than requested? The source can contain fewer captions, the character cap can truncate the video, or the spending limit can stop delivery. Check OUTPUT, piece_count and transcript_truncated.
Why does an API run get blocked? Set native residential routing explicitly. The API default remains false for compatibility. Proxy changes improve access but cannot guarantee it.
Can it transcribe audio or download a whole channel? No. It collects existing captions from individual public video links; it does not generate speech-to-text or discover channel uploads.
For support, share a run ID and sanitized input through the Actor's Issues tab.